我有以下课程:
ApplicationAndConfiguration类
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类
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类
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; } }
当我启动应用程序并将其作为独立的jar或IDE(Eclipse)运行时,完全没有问题,一切都按预期工作.
但是,我想编写一个单元测试来测试我的MyRestController类......我得到一个NPE因为Autowired字段util为null(在MyRestController类中).
这是我的测试类:
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!"))); } }
我肯定错过了一些东西,以便我的Autowired字段在测试期间得到填充,而不仅仅是在标准应用程序执行期间......
任何指针为什么它不起作用?
从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; .. .. }
所有这些实例都将按预期自动装配!甚至发布者的Spring事件也按预期工作,如https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2.
MockMvc独立设置用于单元测试.在测试中创建Spring上下文时,您正在进行集成测试.不要混用这两种类型的测试.
所以只需改变它:
@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(); }