pdc*_*pdc 5 java hamcrest jsonpath
我正在使用 JsonPath 来测试 API 的 REST 端点。我的测试用例看起来像这样。
首先我创建新对象
class Item {
String name;
int id;
List<String> places;
}
String name = "Randomname" + new Random().nextLong();
JSONObject obj = new Item(name, 3, Arrays.asList("Rome3", "London3", "Paris3"));
post("/items").content(obj);
Run Code Online (Sandbox Code Playgroud)
然后我得到所有项目的列表,并检查我刚刚创建的项目是否在列表中。
mockMvc.perform(get("/api/v1/test"))
.andExpect(jsonPath("$.data[*].name", hasItems("item 1", "item 2"))) // Fine
.andExpect(jsonPath("$.data[?(@.id == 1)].name", contains("item 1")))
.andExpect(jsonPath("$.data[?(@.id == 1)].places", contains(contains("Rome1", "London1", "Paris1"))))
.andReturn();
Run Code Online (Sandbox Code Playgroud)
这可行,但我认为我做得不对,因为我有一个嵌套的contains(contains()). (我已将完整的 JSON 响应放在本文末尾。)
问题是因为 JsonPath 表达式返回一个列表,所以我需要使用列表匹配器。例如,不要写这个
jsonPath("$.data[?(@.id == 1)].name", is("item 1"))
Run Code Online (Sandbox Code Playgroud)
我需要这样写
jsonPath("$.data[?(@.id == 1)].name", contains("item 1"))
Run Code Online (Sandbox Code Playgroud)
因为 JsonPath 表达式将返回一个包含一个元素的 JSON 列表
[
"item 1"
]
Run Code Online (Sandbox Code Playgroud)
这还不错,但是对于列表来说情况会更糟,例如尝试检查我的变量位置中的字符串列表是否包含我想要的内容。返回的 JSON 是列表的列表,因此这个 JsonPath 表达式
jsonPath("$.data[?(@.id == 1)].places"
Run Code Online (Sandbox Code Playgroud)
将返回这个
[
[
"Rome2",
"London3",
"Paris3"
]
]
Run Code Online (Sandbox Code Playgroud)
所以它需要一个嵌套的 hasItems
jsonPath("$.data[?(@.id == 1)].places", hasItems(hasItems("Rome1", "London1")))
Run Code Online (Sandbox Code Playgroud)
这确实有效,但这样做只会让我感觉我没有正确地做这件事,而且我错过了一些东西。
所以我的问题是,处理检查/匹配列表列表的适当方法是什么?
是否有更好的方法来验证端点返回的 JSON?