Spring Boot MockMvc如何验证JSON数组中对象的顺序关系?
优雅验证JSON数组元素的递增/递减关系
嘿,你这个需求其实不用自己折腾复杂的自定义Matcher,AssertJ已经提供了现成的严格递增/递减断言,结合Spring MockMvc用起来超优雅!
最推荐的AssertJ方案
这种方式把响应提取后用AssertJ的原生断言,代码直观且完全满足你的需求:
// 执行请求并获取结果 MvcResult result = mockMvc.perform(get("/datas") .param("start", "5") .param("size", "2")) .andExpect(status().isOk()) .andReturn(); // 解析响应体为JSON节点 String responseBody = result.getResponse().getContentAsString(); JsonNode dataArray = new ObjectMapper().readTree(responseBody).get("data"); // 提取id和timestamp列表 List<Long> ids = new ArrayList<>(); List<String> timestamps = new ArrayList<>(); for (JsonNode item : dataArray) { ids.add(item.get("id").asLong()); timestamps.add(item.get("timestamp").asText()); } // 用AssertJ做严格断言 assertThat(ids).isStrictlyIncreasing(); assertThat(timestamps).isStrictlyDecreasing();
为什么这个方案好?
- 现成方法直接用:AssertJ的
isStrictlyIncreasing()会自动验证每个元素严格大于前一个,isStrictlyDecreasing()同理,完全不用自己写比较逻辑。 - 时间字符串直接兼容:你提到的ISO格式timestamp字符串可以直接用字典序比较,
isStrictlyDecreasing()完全能正确验证时间的先后顺序。 - 代码可读性高:一眼就能看出来你要验证什么逻辑,维护起来超方便。
备选:Hamcrest结合排序验证(不推荐,不如AssertJ简洁)
如果你坚持想用Hamcrest的内置匹配器,也可以通过对比原列表和排序后列表的方式实现,但需要额外验证无重复(因为严格递增不允许元素相等):
// 提取列表的步骤和上面一致 List<Long> sortedIds = new ArrayList<>(ids); Collections.sort(sortedIds); // 验证原列表等于升序列表(确保递增),且无重复(确保严格递增) assertThat(ids, equalTo(sortedIds)); assertThat(new HashSet<>(ids).size(), equalTo(ids.size())); // 时间戳同理,排序后反向对比 List<String> sortedTimestamps = new ArrayList<>(timestamps); Collections.sort(sortedTimestamps, Collections.reverseOrder()); assertThat(timestamps, equalTo(sortedTimestamps));
但这种方法需要多写几步,而且逻辑不如AssertJ的断言直观,所以还是优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者Dirk Schumacher
相关产品推荐
相关产品推荐

