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

MockMvc断言LocalDateTime与List类型匹配失败问题咨询

核心原因

MockMvc的JsonPath断言默认只会将JSON返回值解析为Java原生基础类型、字符串、Map、List结构,不会自动反序列化为自定义POJO类、LocalDateTime这类JDK扩展类型,两边类型不匹配自然会抛出断言错误。

两个错误的具体说明与解决

1. LocalDateTime类型断言错误

错误原因:JSON本身没有原生时间类型,序列化后返回的createdAt是ISO格式的字符串,JsonPath读取出的实际值是String类型,和你传入的LocalDateTime对象类型不一致,即使字面量相同也会判定不相等。
最简单的解决方式:直接将预期的LocalDateTime转为对应格式的字符串再对比:

.andExpect(jsonPath("$.createdAt", is(control.getCreatedAt().toString())))

如果你的接口配置了自定义时间序列化格式,用对应的DateTimeFormatter把LocalDateTime转成对应字符串即可。

2. Set类型断言错误

错误原因:JsonPath读取到的scenarios实际是List<Map<String,Object>>结构,每个元素是键值对形式的Map,和你传入的自定义Scenario对象属于完全不同的类型,equals对比直接失败;另外即使实现了自动反序列化,你的Scenario类没有重写equals和hashCode方法,也会导致对象对比不通过。
两种可选解决方案:

  • 方案一(无需额外配置,推荐):拆分断言集合的各个字段
.andExpect(jsonPath("$.scenarios.length()", is(2)))
.andExpect(jsonPath("$.scenarios[0].id", is(1)))
.andExpect(jsonPath("$.scenarios[0].name", is("Max")))
.andExpect(jsonPath("$.scenarios[1].id", is(2)))
.andExpect(jsonPath("$.scenarios[1].name", is("Average")))
  • 方案二:直接将整个响应体反序列化为Control对象后对比
    先给Control、Scenario类重写equals和hashCode方法,再按如下方式写断言:
MvcResult result = mockMvc.perform(get("/control/find/" + control.getId()))
        .andExpect(status().isOk())
        .andReturn();
// 注意ObjectMapper要注册JavaTimeModule支持LocalDateTime反序列化
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
Control respControl = objectMapper.readValue(result.getResponse().getContentAsString(), Control.class);
assertEquals(control, respControl);

修改后的完整断言示例(无需额外配置)

mockMvc.perform(get("/control/find/" + control.getId()))
      .andDo(print())
      .andExpect(status().isOk())
      .andExpect(jsonPath("$.id", equalTo(control.getId()), Long.class))
      .andExpect(jsonPath("$.name", equalTo(control.getName())))
      .andExpect(jsonPath("$.createdAt", is(control.getCreatedAt().toString())))
      .andExpect(jsonPath("$.scenarios.length()", is(2)))
      .andExpect(jsonPath("$.scenarios[0].id", is(1)))
      .andExpect(jsonPath("$.scenarios[0].name", is("Max")))
      .andExpect(jsonPath("$.scenarios[1].id", is(2)))
      .andExpect(jsonPath("$.scenarios[1].name", is("Average")));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:39:03