MockMVC返回200状态但缺失data字段问题排查求助
MockMvc返回200状态码但响应缺失data字段
问题现象
调用/users接口时,MockMvc返回200状态码,但响应体仅包含{"status":"success"},缺失预期的data字段。测试中已确认users列表非空。
测试代码
@Test public void shouldReturnAll() throws Exception { when(userService.getAll()).thenReturn(users); // 注:'users'列表非空,已确认。 MvcResult response = this.mvc.perform(get("/users")) .andExpect(status().isOk()) .andExpect(jsonPath("$.data", hasSize(2))) .andReturn(); }
响应内容
MockHttpServletResponse: Status = 200 Error message = null Headers = [Content-Type:"application/json"] Content type = application/json Body = {"status":"success"} Forwarded URL = null Redirected URL = null Cookies = []
Controller代码(批量查询接口)
@GetMapping public ResponseEntity<Response> getAll() { List<User> users = userService.getAll(); Response resp = new Response(StatusMessage.SUCCESS, users); return new ResponseEntity<Response>(resp, HttpStatus.OK); }
补充说明:单个用户查询接口正常
测试代码
@Test public void getUserByIdTest() throws Exception { when(this.userService.getUserById(any(Long.class))).thenReturn(user); MvcResult response = this.mvc.perform(get("/users/{id}", user.getId())) .andExpect(status().isOk()) .andExpect(jsonPath("$.data.id", is(user.getId().intValue()))) .andExpect(jsonPath("$.data.name", is(user.getName()))) .andReturn(); }
Controller代码
@GetMapping(value = "/{id}") public ResponseEntity<Response> getUserById(@PathVariable Long id) throws Exception { try { User user = userService.getUserById(id); Response resp = new Response(StatusMessage.SUCCESS, user); return new ResponseEntity<Response>(resp, HttpStatus.OK); } catch (Exception e) { throw new Exception(e.getMessage()); } }
Response对象类代码
@Data @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Response<T> { private String status; private T data; public Response(StatusMessage status, T data) { this.status = status.getStatusMessage(); this.data = data; } }
问题原因与解决方案
原因
问题出在Response类上的@JsonInclude(JsonInclude.Include.NON_EMPTY)注解:
- 该注解会让Jackson序列化时仅包含非空字段。对于集合类型(如
List<User>),Jackson会将空集合(size=0)视为“EMPTY”,从而跳过data字段的序列化。 - 单个用户查询正常是因为传入的
data是单个User对象,只要对象非null就不属于“EMPTY”范畴,会被正常序列化。
解决方案
根据需求选择以下两种方式之一:
- 修改JsonInclude注解:将
@JsonInclude(JsonInclude.Include.NON_EMPTY)改为@JsonInclude(JsonInclude.Include.NON_NULL)。这样只要data字段不为null,无论集合是否为空都会被序列化:@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class Response<T> { // ... 原有代码 } - 确认集合有效性:如果坚持使用
NON_EMPTY,需再次验证Mock中的users列表是否真的包含预期元素(比如是否在测试前正确初始化列表并添加了2个User对象)。
内容的提问来源于stack exchange,提问作者Muse
相关产品推荐
相关产品推荐

