MockMvc测试接口JSON路径断言失败:响应体为空
Spring Boot JUnit测试接口返回空响应体导致断言失败的排查与解决
问题现象
- 执行
testCountEndPoint测试用例调用/api/v1/user/100/notifications/count接口时,断言$.data.count失败,报错:java.lang.AssertionError: No value at JSON path "$.data.count" - 根因关联错误:
java.lang.IllegalArgumentException: json can not be null or empty - 接口返回状态码200,但响应体为空
- 已Mock
InAppNotificationRepository.count()方法返回5L,但控制器未输出预期JSON结构
排查与解决步骤
1. 检查控制器方法的返回值逻辑
这是最常见的原因:控制器方法没有正确返回封装了data.count的响应对象,甚至返回了void类型。
- 错误示例:
@GetMapping("/api/v1/user/{userId}/notifications/count") public void getNotificationCount(@PathVariable Long userId) { // 仅调用Repository,未返回任何数据 inAppNotificationRepository.countByUserId(userId); }
- 修正写法(假设项目使用自定义响应封装类
ResultDTO):
@GetMapping("/api/v1/user/{userId}/notifications/count") public ResultDTO getNotificationCount(@PathVariable Long userId) { Long count = inAppNotificationRepository.countByUserId(userId); // 封装成包含data.count的结构 return ResultDTO.success(Map.of("count", count)); }
2. 确认Mock方法的签名匹配度
测试中Mock的Repository方法必须和控制器实际调用的方法签名完全一致,否则Mock逻辑不会生效,可能导致返回null。
- 错误示例(控制器调用
countByUserId,但Mock了count):
when(inAppNotificationRepository.count()).thenReturn(5L);
- 修正后的Mock代码:
// 匹配控制器调用的countByUserId方法,参数对应测试用例的100L when(inAppNotificationRepository.countByUserId(100L)).thenReturn(5L);
3. 验证测试中的响应解析逻辑
在测试方法中临时打印响应体,确认控制器是否真的没有返回数据:
MvcResult result = mockMvc.perform(get("/api/v1/user/100/notifications/count") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn(); // 打印响应体,排查是否为空 System.out.println("Response Body: " + result.getResponse().getContentAsString());
如果输出为空,回到步骤1确认控制器返回逻辑。
4. 排查全局响应处理器/拦截器
检查项目中是否存在ResponseBodyAdvice、全局拦截器等组件,是否因为逻辑错误清空了响应体:
- 临时注释这类组件,重新运行测试,确认是否恢复正常;
- 若恢复,排查组件中的判断逻辑(比如是否错误地将非空返回值转为null)。
内容的提问来源于stack exchange,提问作者Saurabh Dhage
相关产品推荐
相关产品推荐

