Spring MockMvc:以任何顺序匹配JSON对象的集合
2022-09-02 19:53:28
我有一个API端点,当使用GET调用时,它会在正文中返回一个JSON对象数组,如下所示:
[
{"id": "321", "created": "2019-03-01", "updated": "2019-03-15"},
{"id": "123", "created": "2019-03-02", "updated": "2019-03-16"}
]
我想用Spring MockMvc测试用例检查身体。该语句当前如下所示:
mockMvc.perform(get("/myapi/v1/goodstuff").
andExpect(status().isOk()).
andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)).
andExpect(jsonPath("$.*", isA(ArrayList.class))).
andExpect(jsonPath("$.*", hasSize(2))).
andExpect(jsonPath("$[0].id", is("321"))).
andExpect(jsonPath("$[0].created", is("2019-03-01"))).
andExpect(jsonPath("$[0].updated*", is("2019-03-15"))).
andExpect(jsonPath("$[1].id", is("1232"))).
andExpect(jsonPath("$[1].created", is("2019-03-02"))).
andExpect(jsonPath("$[1].updated*", is("2019-03-16")));
但是,我的 API 的实现并不能保证返回数组中 JSON 对象的顺序。如果这是一个字符串数组,我会通过 生成的匹配器解决这个问题。但是我在他们的文档中看不到任何适合我的情况的匹配器,也没有在Spring文档中的方法描述中找到任何线索org.hamcrest.collection.IsIterableContainingInAnyOrder<T>.containsInAnyOrder
jsonPath
通过快速搜索,我没有设法找到与我在SO上的情况相关的任何内容,除了我上面描述的字符串情况列表之外。当然,我可以将 JSON 对象转换为字符串。
但是我想知道,对于JSON对象列表,我可以解决这个问题,逐个比较每个对象的每个字段(如上面的代码片段所示),但忽略集合中对象的顺序?
更新:Zgurskyi提出了一个解决方案,可以帮助我原来的简化示例。但是,在现实生活中的实际示例中,还有 2 个输入:
- 字段数为 10-20 而不是 3
- 并非所有的匹配器都是普通的,例如:
is
(更接近我的原始代码)
mockMvc.perform(get("/myapi/v1/greatstuff").
andExpect(status().isOk()).
andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)).
andExpect(jsonPath("$.*", isA(ArrayList.class))).
andExpect(jsonPath("$.*", hasSize(2))).
andExpect(jsonPath("$[0].id", is("321"))).
andExpect(jsonPath("$[0].did", anything())).
andExpect(jsonPath("$[0].createdTs", startsWith("2019-03-01"))).
andExpect(jsonPath("$[0].updatedTs", startsWith("2019-03-15"))).
andExpect(jsonPath("$[0].name", equalToIgnoringCase("wat"))).
andExpect(jsonPath("$[0].stringValues", containsInAnyOrder("a","b","c"))).
andExpect(jsonPath("$[1].id", is("1232"))).
andExpect(jsonPath("$[1].did", anything())).
andExpect(jsonPath("$[1].createdTs", startsWith("2019-03-01"))).
andExpect(jsonPath("$[1].updatedTs", startsWith("2019-03-15"))).
andExpect(jsonPath("$[1].name", equalToIgnoringCase("taw"))).
andExpect(jsonPath("$[1].stringValues", containsInAnyOrder("d","e","f"))).
andReturn();
到目前为止,我似乎没有什么比实现我自己的匹配器类更好的了。
或。。。我可以吗?