You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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”范畴,会被正常序列化。

解决方案

根据需求选择以下两种方式之一:

  1. 修改JsonInclude注解:将@JsonInclude(JsonInclude.Include.NON_EMPTY)改为@JsonInclude(JsonInclude.Include.NON_NULL)。这样只要data字段不为null,无论集合是否为空都会被序列化:
    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class Response<T> {
        // ... 原有代码
    }
    
  2. 确认集合有效性:如果坚持使用NON_EMPTY,需再次验证Mock中的users列表是否真的包含预期元素(比如是否在测试前正确初始化列表并添加了2个User对象)。

内容的提问来源于stack exchange,提问作者Muse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:30:56