我在Spring-Boot 1.4中有以下Rest Controller
和单元测试:
@RestController
public class HealthCheckerController {
@Autowired
private InstanceRepository instanceRepository;
@RequestMapping(value = "/healthchecker", method = RequestMethod.GET)
@ResponseBody
public List<Instance> findAll() {
return this.instanceRepository.findAll();
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class HealthCheckerControllerTest {
private MockMvc mvc;
@Autowired
private InstanceRepository instanceRepository;
@Before
public void setUp() throws Exception {
mvc = MockMvcBuilders.standaloneSetup(new HealthCheckerController()).build();
this.instanceRepository.deleteAll();
Instance first = new Instance("10.20.30.40", "ami-xxxxxxxx");
Instance second = new Instance("10.20.30.41", "ami-xxxxxxxx");
this.instanceRepository.save(first);
this.instanceRepository.save(second);
for (Instance instance : this.instanceRepository.findAll()) {
System.out.println(instance);
}
}
@Test
public void testHealthChecker() throws Exception {
mvc.perform(get("/healthchecker")).andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].ipaddress", is("10.20.30.40")))
.andExpect(jsonPath("$[0].ami", is("ami-xxxxxxxx")))
.andExpect(jsonPath("$[1].ipaddress", is("10.20.30.41")))
.andExpect(jsonPath("$[1].ami", is("ami-xxxxxxxx")));
}
}
但是,当我执行单元测试时,它会给我以下错误:
Tests run: 21, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 19.83 sec <<< FAILURE! - in TestSuite
testHealthChecker on testHealthChecker(cloudos.HealthCheckerControllerTest)(cloudos.HealthCheckerControllerTest) Time elapsed: 0.193 sec <<< FAILURE!
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
at cloudos.HealthCheckerController.findAll(HealthCheckerController.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
at cloudos.HealthCheckerControllerTest.testHealthChecker(HealthCheckerControllerTest.java:48)
从UI访问它可以正常工作:
[{"ipaddress":"10.20.30.40","ami":"ami-xxxxxxxx"},{"ipaddress":"10.20.30.41","ami":"ami-xxxxxxxx"}]
我理解问题是private InstanceRepository instanceRepository
中unit test
没有被初始化,所以当它在HealthCheckerController
内被访问时,它是空的,但是& #39;不是@Autowired
的目的吗?
我怎么能解决这个问题?
答案 0 :(得分:3)
当您使用MockMvcBuilders.standaloneSetup
时,您需要手动设置您的控制器对象(而不是单元测试)
如果您想使用完整的Spring上下文(所有@Autowired
个字段都可用),您需要使用MockMvcBuilders.webAppContextSetup
这应该有效:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class HealthCheckerControllerTest {
private MockMvc mvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private InstanceRepository instanceRepository;
@Before
public void setUp() throws Exception {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
this.instanceRepository.deleteAll();
Instance first = new Instance("10.20.30.40", "ami-xxxxxxxx");
Instance second = new Instance("10.20.30.41", "ami-xxxxxxxx");
this.instanceRepository.save(first);
this.instanceRepository.save(second);
for (Instance instance : this.instanceRepository.findAll()) {
System.out.println(instance);
}
}
@Test
public void testHealthChecker() throws Exception {
mvc.perform(get("/healthchecker")).andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].ipaddress", is("10.20.30.40")))
.andExpect(jsonPath("$[0].ami", is("ami-xxxxxxxx")))
.andExpect(jsonPath("$[1].ipaddress", is("10.20.30.41")))
.andExpect(jsonPath("$[1].ami", is("ami-xxxxxxxx")));
}
}
您最终可以尝试将构造函数添加到控制器并手动将现有存储库注入新创建的控制器:
@RestController
public class HealthCheckerController {
@Autowired
private InstanceRepository instanceRepository;
public HealthCheckerController(InstanceRepository instanceRepository) {
this.instanceRepository = instanceRepository;
}
@RequestMapping(value = "/healthchecker", method = RequestMethod.GET)
@ResponseBody
public List<Instance> findAll() {
return this.instanceRepository.findAll();
}
}
并且您的mvc配置应如下所示:
mvc = MockMvcBuilders.standaloneSetup(new HealthCheckerController(instanceRepository)).build();