如何让Maven/Mockito Mock MVC测试输出更详细的堆栈跟踪?
如何在Mock MVC测试中获取控制器的详细堆栈跟踪
问题场景
我在Maven项目中使用JUnit 5和spring-boot-starter-test(v1.5)做Mock MVC控制器测试,代码如下:
@ExtendWith(MockitoExtension.class) public class MyControllerTest { ... MockMvc mockMvc; ... @BeforeEach public void setup() throws Exception { ... mockMvc = MockMvcBuilders.standaloneSetup(controller) .setControllerAdvice(new RestResponseEntityExceptionHandler()) .build(); } void testGetMethod() throws Exception { ... mocking ... mockMvc .perform(get("/mypath").contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); }
当控制器内部抛出NullPointerException时,测试失败的堆栈跟踪只显示测试用例的行号,看不到控制器里的具体出错位置:
> mvn clean test -Dtest=MyControllerTest ... [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.676 s <<< FAILURE! - in com.rmyco.feature.controller.MyControllerTest [ERROR] com.rmyco.feature.controller.MyControllerTest.testGetMethod Time elapsed: 1.663 s <<< ERROR! org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException at com.rmyco.feature.controller.MyControllerTest.testGetMethod(MyControllerTest.java:103) Caused by: java.lang.NullPointerException at com.rmyco.feature.controller.MyControllerTest.testGetMethod(MyControllerTest.java:103) [INFO] [INFO] Results: [INFO] [ERROR] Errors: [ERROR] MyControllerTest.testGetMethod:103 » NestedServlet
解决方法
1. 调整MockMvc的异常处理器配置
默认的RestResponseEntityExceptionHandler会包装异常,导致原始堆栈被截断。可以直接移除这个配置,让MockMvc保留完整的异常堆栈:
@BeforeEach public void setup() throws Exception { mockMvc = MockMvcBuilders.standaloneSetup(controller) // 移除setControllerAdvice,避免异常被包装 .build(); }
如果需要自定义异常处理逻辑,自己实现异常处理器时要确保不丢失原始异常的堆栈信息。
2. 配置Maven Surefire插件输出完整堆栈
在项目的pom.xml中配置Surefire插件,强制输出完整的堆栈跟踪:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <!-- 适配Spring Boot 1.5版本 --> <configuration> <fullStackTrace>true</fullStackTrace> <trimStackTrace>false</trimStackTrace> </configuration> </plugin> </plugins> </build>
配置后重新运行测试,就能看到完整的异常链,包括控制器里的出错行。
3. 启用MockMvc的调试打印
在测试请求中添加andDo(print()),可以打印请求、响应的详细信息,包括完整的异常堆栈:
mockMvc .perform(get("/mypath").contentType(MediaType.APPLICATION_JSON)) .andDo(print()) // 输出调试信息,包含完整异常堆栈 .andExpect(status().isOk());
4. 调整日志级别
运行测试时添加日志参数,让Spring Web模块输出更详细的日志,包括异常细节:
mvn clean test -Dtest=MyControllerTest -Dlogging.level.org.springframework.web=DEBUG
也可以在测试类的resources目录下添加logback-test.xml配置日志级别,确保能捕获到异常的完整堆栈。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

