JUnit5测试Spring GetMapping接口预期200却返回500错误排查求助
问题根因&修复方案
核心错误点
- 请求参数大小写不匹配:接口中
@RequestParam指定的参数名为Param1(首字母大写P),但单元测试传入的参数名为param1(首字母小写p),Spring MVC参数绑定直接失败抛出异常,这是最常见的触发500的原因。 - Mock方法不完整:你仅Mock了
findService.findService()的返回值为ServiceResponse的Mock对象,但没有为该Mock对象的getDataResponse()方法指定返回值,Mockito对未指定Mock规则的方法默认返回null,后续构造ResponseEntity或序列化时会触发空指针异常。 - Mockito参数匹配可能失效:如果
Util.convertToString()方法内部存在随机值、时间戳、动态解析逻辑,会导致测试代码中预计算的convertedStirngToFind和接口实际执行时生成的参数值不一致,Mockito的Mock规则触发失败,findService.findService()返回null触发空指针。 - 静态工具类未Mock:
Util类的getTokenAsJson、convertToString都是静态方法,@WebMvcTest不会自动Mock静态类,若这两个方法内部抛出异常(比如token解析失败、格式校验不通过),也会直接返回500。
排查验证步骤
- 直接查看
andDo(print())输出的完整响应内容,你当前只看了状态码,print()会把完整的异常堆栈、错误消息打印在控制台,可直接定位具体异常类型。 - 断点不生效是因为
@WebMvcTest返回的是Controller的代理对象,直接在Controller源码打断点可能无法命中,可以在测试代码的mockMvc.perform行打断点后Step Into进入执行流程,或者直接开启Debug模式运行测试,控制台会输出完整的异常栈信息。
修复代码示例
- 修正参数名匹配
// 测试代码中参数名和接口保持一致 RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/sample/findData/rest") .header("Authorization", token) .param("Param1", param1);
- 补充Mock规则
// 补充ServiceResponse的getDataResponse方法Mock ServiceResponse mockServiceResponse = mock(ServiceResponse.class); ResponseObj mockData = new ResponseObj(); // 可根据需求填充字段 Mockito.when(mockServiceResponse.getDataResponse()).thenReturn(mockData); // 临时用任意参数匹配验证Mock逻辑是否生效,确认后再改回精确匹配 Mockito.when(findService.findService(Mockito.any(String.class))) .thenReturn(mockServiceResponse);
- 若静态工具类抛异常,增加静态方法Mock(需要Mockito 3.4+版本支持)
try(MockedStatic<Util> mockedUtil = Mockito.mockStatic(Util.class)) { mockedUtil.when(() -> Util.getTokenAsJson(token)).thenReturn(jwtToken); mockedUtil.when(() -> Util.convertToString(param1,jwtToken)).thenReturn(convertedStirngToFind); // 执行mockMvc请求逻辑 }
内容的提问来源于stack exchange,提问作者Reese
相关产品推荐
相关产品推荐

