Java Spring Boot 单元测试自动连线
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34436664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot Unit Test Autowired
提问by hublo
I have the following classes :
我有以下课程:
ApplicationAndConfiguration class
应用程序和配置类
package mypackage.service;
import mypackage.service.util.MyUtility;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class ApplicationAndConfiguration {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(ApplicationAndConfiguration.class, new String[]{});
}
@Bean(initMethod="init")
public MyUtility birtUtil() {
return new MyUtility();
}
}
MyRestController class
MyRestController 类
package mypackage.service.controllers;
import mypackage.service.util.MyUtility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@Autowired
private MyUtility util;
@RequestMapping("/getLibraryName")
public String getMessageFromRest(@RequestParam String name) {
return "name was " + name + "//" + util.getMessage();
}
}
MyUtility class
MyUtility 类
package mypackage.service.util;
public class MyUtility {
private String message;
public void init() {
setMessage("MyUtility correctly initialized!");
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
When I start the application and run it as an independant jar, or from the IDE (Eclipse), no problem at all, everything works as expected.
当我启动应用程序并将其作为独立 jar 或从 IDE (Eclipse) 运行时,完全没有问题,一切都按预期工作。
However, I want to write a unit test to test my MyRestControllerclass ... and I'm getting a NPE because the Autowired field util is null (within MyRestControllerclass).
但是,我想编写一个单元测试来测试我的MyRestController类……并且我得到了一个 NPE,因为 Autowired 字段 util 为空(在MyRestController类中)。
Here is my test class :
这是我的测试课:
package mypackage.service.controllers;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import mypackage.service.ApplicationAndConfiguration;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@SpringApplicationConfiguration(classes = ApplicationAndConfiguration.class)
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class TestController {
private MockMvc mvc;
@Before
public void setup() throws Exception {
mvc = MockMvcBuilders.standaloneSetup(new MyRestController()).build();
}
@Test
public void MyTestController() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/getLibraryName").param("name", "test").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("name was test//MyUtility correctly initialized!")));
}
}
I'm definitely missing something so that my Autowired field gets filled during tests, and not only during standard application execution ...
我肯定遗漏了一些东西,所以我的 Autowired 字段在测试期间被填充,而不仅仅是在标准应用程序执行期间......
Any pointer why it doesn't work ?
任何指针为什么它不起作用?
采纳答案by luboskrnac
MockMvc standalone setup is for unit testing. You are doing integration testing when you are creating Spring context in test. Don't mix these two types of testing.
MockMvc 独立设置用于单元测试。当您在测试中创建 Spring 上下文时,您正在进行集成测试。不要混合这两种类型的测试。
So just change it this way:
所以只要这样改变它:
@SpringApplicationConfiguration(classes = ApplicationAndConfiguration.class)
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class TestController {
private MockMvc mvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setup() throws Exception {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
回答by Marcello de Sales
Since SpringBoot 1.4, all the classes changed and deprecated https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4.0-M2-Release-Notes. Replace the Runner and Configuration with the ones below. SpringRunner will detect the test framework for you.
从 SpringBoot 1.4 开始,所有类都更改并弃用了https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4.0-M2-Release-Notes。用下面的替换 Runner 和 Configuration。SpringRunner 将为您检测测试框架。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { FileService.class, AppProperties.class, DownloadConfigEventHandler.class })
@EnableConfigurationProperties
public class ConfigMatrixDownloadAndProcessingIntegrationTests extends ConfigMatrixDownloadAbstractTest {
// @Service FileService
@Autowired
private FileService fileService;
// @Configuration AppProperties
@Autowired
private AppProperties properties;
// @Compoenet DownloadConfigEventHandler
@Autowired
private DownloadConfigEventHandler downloadConfigEventHandler;
..
..
}
All of these instances will be autowired as expected! Even Spring Events with the Publisher is working as expected as in https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2.
所有这些实例都将按预期自动装配!即使 Spring Events with the Publisher 也能像https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2 中的预期那样工作。