Java 弹簧启动单元测试自动连线
我有以下课程: 应用程序和配置类Java 弹簧启动单元测试自动连线,java,spring,unit-testing,spring-boot,autowired,Java,Spring,Unit Testing,Spring Boot,Autowired,我有以下课程: 应用程序和配置类 package mypackage.service; import mypackage.service.util.MyUtility; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.Applicati
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();
}
}
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;
}
}
MyUtility类
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();
}
}
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,因为自动连接字段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!")));
}
}
我肯定错过了一些东西,所以我的自动连线字段在测试期间被填充,而不仅仅是在标准应用程序执行期间
任何一个指针,为什么它不工作?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();
}
自SpringBoot 1.4以来,所有的类都发生了变化并被弃用。将流道和配置替换为以下配置。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事件也如中所预期的那样工作。请注意,使用构造函数注入而不是字段注入将有助于识别此类问题,并使独立单元测试更容易。即使没有classes参数,它也能为我工作。感谢
@RunWith
仅适用于JUnit4,对于JUnit5,请使用@extendedwith(SpringExtension.class)
。