Spring Boot使用MockMvc測試時的一次小坑
阿新 • • 發佈:2019-02-15
Spring Boot 版本為 1.5.13.RELEASE
一個基本的RESTful API小案例,正常啟動Spring Boot無異常,介面訪問全部正常通過。
在其他配置全部一致的情況下,使用MockMvc進行測試丟擲異常:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:71) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:160) at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:127) at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:151) at com.tanwubo.Demo04ApplicationTests.userControllerTest(Demo04ApplicationTests.java:70) 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:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.NullPointerException at com.tanwubo.controller.UserController.findById(UserController.java:30) 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:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) 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:967) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ... 39 more
測試類:
@RunWith(SpringRunner.class) @SpringBootTest(classes = { Demo04Application.class, MockServletContext.class }) public class Demo04ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new UserController()).build(); } @Test public void userControllerTest() throws Exception { // 測試UserController RequestBuilder request = null; request = get("/users/2"); mvc.perform(request).andExpect(status().isOk()).andExpect(content().string(equalTo( "{\"msg\":\"成功\",\"code\":200,\"user\":{\"id\":2,\"username\":\"admin\",\"password\":\"admin\"}}"))); } }
後將MockMvc的建立方式由 mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
修改為 mvc = MockMvcBuilders.webAppContextSetup(this.context).build();測試成功。具體原因不詳,故做此記錄。
修改後的程式碼:
@RunWith(SpringRunner.class) @SpringBootTest(classes = { Demo04Application.class, MockServletContext.class }) public class Demo04ApplicationTests { @Autowired private WebApplicationContext context; private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); } @Test public void userControllerTest() throws Exception { // 測試UserController RequestBuilder request = null; request = get("/users/2"); mvc.perform(request).andExpect(status().isOk()).andExpect(content().string(equalTo( "{\"msg\":\"成功\",\"code\":200,\"user\":{\"id\":2,\"username\":\"admin\",\"password\":\"admin\"}}"))); } }