如何用Rest-Assured+Java从无标签嵌套列表提取指定键值对
问题:从嵌套JSON数组提取指定索引的外层字段(Rest-Assured+TestNG)
需要从接口返回的嵌套JSON数组中提取索引[1]位置的外层userId和oneAccountId值(层级中存在多个userId键,仅需最外层的)。Postman测试脚本可正常提取并存储为变量,但Rest-Assured+TestNG框架中的当前代码返回null,求正确实现方案。
示例响应体
[ { "userId": 4813, "oneAccountId": 20785114, "userOptions": [ { "userOptionsId": null, "userId": null, }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": 16093, "userId": 4813, } ], "accessLocations": null }, { "userId": 56725, "oneAccountId": 66443583, "userOptions": [ { "userOptionsId": null, "userId": null, }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": 27135, "userId": 56725, }, { "userOptionsId": 27145, "userId": 56725, } ], "accessLocations": null }, { "userId": 21455, "oneAccountId": 35993484, "userOptions": [ { "userOptionsId": 29253, "userId": 21455, }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": 29023, "userId": 21455, }, { "userOptionsId": 3843, "userId": 21455, }, { "userOptionsId": 3615, "userId": 21455, } ], "accessLocations": null }, { "userId": 52903, "oneAccountId": 61477703, "userOptions": [ { "userOptionsId": null, "userId": null }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": null, "userId": null, }, { "userOptionsId": 24303, "userId": 52903, }, { "userOptionsId": 24313, "userId": 52903, } ], "accessLocations": null } ]
Postman可用代码
const response = JSON.parse(responseBody); pm.environment.set("userId", response[1].userId); pm.environment.set("oneAccountId", response[1].oneAccountId);
当前Rest-Assured错误代码
@Test (dataProvider = "endPoints") public void get_users_associated_to_a_particular_compcode(String endPoints) { Response response = given(). header("Content-Type", "application/json"). header("Authorization", "Bearer " + accessToken). get(endPoints). then(). statusCode(200). contentType(ContentType.JSON). extract().response(); JsonPath extractValue = response.jsonPath(); String userID = extractValue.getList("userId").get(1).toString(); String oneAccountID = extractValue.getList("oneAccountId").get(1).toString(); }
错误原因
原代码中extractValue.getList("userId")会递归遍历整个JSON结构,收集所有名为userId的字段值(包括嵌套在userOptions数组里的userId),因此get(1)拿到的并不是外层数组索引1的对象的userId,导致结果不符合预期甚至返回null。
正确实现方案
方案1:直接通过JsonPath索引定位(推荐)
利用JsonPath语法直接定位到外层数组的第1个元素,再提取对应的字段:
@Test (dataProvider = "endPoints") public void get_users_associated_to_a_particular_compcode(String endPoints) { Response response = given() .header("Content-Type", "application/json") .header("Authorization", "Bearer " + accessToken) .get(endPoints) .then() .statusCode(200) .contentType(ContentType.JSON) .extract() .response(); JsonPath extractValue = response.jsonPath(); // 直接定位到外层数组索引1的对象,提取指定字段 Integer userId = extractValue.get("[1].userId"); Integer oneAccountId = extractValue.get("[1].oneAccountId"); // 如需转成String类型 String userIdStr = String.valueOf(userId); String oneAccountIdStr = String.valueOf(oneAccountId); }
方案2:先获取整个数组再提取对象字段
先把外层数组转为List对象,再取指定索引的元素,最后提取字段:
@Test (dataProvider = "endPoints") public void get_users_associated_to_a_particular_compcode(String endPoints) { Response response = given() .header("Content-Type", "application/json") .header("Authorization", "Bearer " + accessToken) .get(endPoints) .then() .statusCode(200) .contentType(ContentType.JSON) .extract() .response(); JsonPath extractValue = response.jsonPath(); // 获取外层整个用户对象数组 List<Map<String, Object>> userList = extractValue.getList("$"); // 取出索引1的用户对象 Map<String, Object> targetUser = userList.get(1); // 提取外层字段 Integer userId = (Integer) targetUser.get("userId"); Integer oneAccountId = (Integer) targetUser.get("oneAccountId"); // 如需转成String类型 String userIdStr = userId.toString(); String oneAccountIdStr = oneAccountId.toString(); }
内容的提问来源于stack exchange,提问作者Jimil Patel
相关产品推荐
相关产品推荐

