Rest Assured 响应 - 验证匹配相同路径的节点
Rest Assured response - validating nodes matching the same path
在我的测试中有这样的响应:
{
"commands": [
{
"type": "com.our.identity.patch",
"value": [
{
"op": "add",
"path": "/claims/gTwfQubKEl4r",
"value": [
"vcvWxlsLKV35"
]
},
{
"op": "add",
"path": "/claims/Jmq6zrG7LKoJ",
"value": [
"iiMQoOWKu2OI"
]
}
]
}
]
}
其中 gTwfQubKEl4r
和 vcvWxlsLKV35
是键值对。
Jmq6zrG7LKoJ
和 iiMQoOWKu2OI
键值对也一样。
响应可以包含许多键值对。
我需要能够验证响应中是否存在某些键和值。
我使用 restassured java
所以我知道我可以使用像 commands.value.path
这样的路径来获取密钥,并使用 commands.value.value
这样的路径来获取我写的这些方法的值:
public String getValueFromResponseBody(Response res, String key){
return res.body().jsonPath().getString(key);
}
public void validateParameterValueInResponseBodyEquals(Response res, String param, String expectedValue){
String value = getValueFromResponseBody(res,param);
Assert.assertEquals(value,expectedValue);
}
传递的 param
是响应中的参数路径,如 commands.value.path
。
但我认为这会给我带来响应主体内与传递的路径匹配的第一个节点,而我需要检查响应内与该路径匹配的所有节点。
可能吗?
I think this will bring me the first node inside the response body
matching the passed path while I need to check against all the nodes
inside the response matching that path
不,它得到了所有的匹配。由于commands
节点和value
节点都是数组,所以会产生list的列表。
List<List<String>> lists = JsonPath.from(res).getList("commands.value.path");
[[/claims/gTwfQubKEl4r, /claims/Jmq6zrG7LKoJ]]
List<String> list = JsonPath.from(res).getList("commands[0].value.path")
[/claims/gTwfQubKEl4r, /claims/Jmq6zrG7LKoJ]
String str = JsonPath.from(res).getString("commands[0].value[0].path");
/claims/gTwfQubKEl4r
解法:
要在一个查询中得到所有的path
,你只需要List<List<String>>
--> List<String>
。您可以在流中尝试 flatMap 或使用其他方式。
List<List<String>> lists = JsonPath.from(res).getList("commands.value.path");
List<String> flat = lists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
flat.forEach(System.out::println);
/claims/gTwfQubKEl4r
/claims/Jmq6zrG7LKoJ
多一个选项:
您可以使用 JsonPath (com.jayway.jsonpath.JsonPath)
List<String> list = JsonPath.read(res, "$..path");
list.forEach(System.out::println);
/claims/gTwfQubKEl4r
/claims/Jmq6zrG7LKoJ
在我的测试中有这样的响应:
{
"commands": [
{
"type": "com.our.identity.patch",
"value": [
{
"op": "add",
"path": "/claims/gTwfQubKEl4r",
"value": [
"vcvWxlsLKV35"
]
},
{
"op": "add",
"path": "/claims/Jmq6zrG7LKoJ",
"value": [
"iiMQoOWKu2OI"
]
}
]
}
]
}
其中 gTwfQubKEl4r
和 vcvWxlsLKV35
是键值对。
Jmq6zrG7LKoJ
和 iiMQoOWKu2OI
键值对也一样。
响应可以包含许多键值对。
我需要能够验证响应中是否存在某些键和值。
我使用 restassured java
所以我知道我可以使用像 commands.value.path
这样的路径来获取密钥,并使用 commands.value.value
这样的路径来获取我写的这些方法的值:
public String getValueFromResponseBody(Response res, String key){
return res.body().jsonPath().getString(key);
}
public void validateParameterValueInResponseBodyEquals(Response res, String param, String expectedValue){
String value = getValueFromResponseBody(res,param);
Assert.assertEquals(value,expectedValue);
}
传递的 param
是响应中的参数路径,如 commands.value.path
。
但我认为这会给我带来响应主体内与传递的路径匹配的第一个节点,而我需要检查响应内与该路径匹配的所有节点。
可能吗?
I think this will bring me the first node inside the response body matching the passed path while I need to check against all the nodes inside the response matching that path
不,它得到了所有的匹配。由于commands
节点和value
节点都是数组,所以会产生list的列表。
List<List<String>> lists = JsonPath.from(res).getList("commands.value.path");
[[/claims/gTwfQubKEl4r, /claims/Jmq6zrG7LKoJ]]
List<String> list = JsonPath.from(res).getList("commands[0].value.path")
[/claims/gTwfQubKEl4r, /claims/Jmq6zrG7LKoJ]
String str = JsonPath.from(res).getString("commands[0].value[0].path");
/claims/gTwfQubKEl4r
解法:
要在一个查询中得到所有的path
,你只需要List<List<String>>
--> List<String>
。您可以在流中尝试 flatMap 或使用其他方式。
List<List<String>> lists = JsonPath.from(res).getList("commands.value.path");
List<String> flat = lists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
flat.forEach(System.out::println);
/claims/gTwfQubKEl4r
/claims/Jmq6zrG7LKoJ
多一个选项:
您可以使用 JsonPath (com.jayway.jsonpath.JsonPath)
List<String> list = JsonPath.read(res, "$..path");
list.forEach(System.out::println);
/claims/gTwfQubKEl4r
/claims/Jmq6zrG7LKoJ