REST Assured:如何使用 JSON 中的嵌套 属性 查找元素并验证其他属性
REST Assured: How to find element using nested property in JSON and validate other properties
经验有限,放心。我们有许多测试,我通常可以在其中找到示例,或者失败 google,但是当我尝试匹配匿名数组中的元素的嵌套 属性 并验证属性时,我被卡住了上下(表亲?)。
示例JSON:
[
{
"id":1,
"type":{
"typeId":3,
"name":"LPM"
},
"status":{
"id":1,
"price":1.20,
"source":172,
"valid":0
}
},
{
"id":2,
"type":{
"typeId":2,
"name":"ST"
},
"status":{
"id":10,
"price":1.20,
"source":172,
"valid":0
}
}
]
我用的是放心,我想在列表中找到type.name
等于LPM的元素,然后验证status.price
、status.source
和status.id
只有那个元素。
当我最初开始验证响应时,数组中只能有一个项目,所以我使用的是:
response.then()
.assertThat()
.body("size", greaterThan(0))
.body("[0].type.name", equalToIgnoringCase("LPM"))
.body("[0].status.id", equalTo(statusId))
.body("[0].status.source", equalTo(sourceId))
.body("[0].status.price", equalTo(price));
然而,这不再保证有效,因为数组中可能有多个元素,并且无法保证顺序。
我已将 body 支票修改为:
response.then()
.assertThat()
.body("size", greaterThan(0))
.body("type.name", hasItem("LPM"))
.body("status.id", hasItem(statusId))
.body("status.source", hasItem(sourceId))
.body("status.price", hasItem(price));
这足以让测试通过,但这引入了 status.id
、status.source
和 status.price
具有 type.name
LPM 的元素的风险可能不正确,但这不会被检测到,因为它们将与具有 type.name
ST.
的元素匹配
所以我希望能够找到具有 LPM 的元素,因为它是 type.name
,我可以保证只有一个,然后 status.id
,status.source
,和 status.price
,仅检查该元素,即 NOT ST 元素。
我试图修改我的 body 匹配器以找到具有我需要的 type.name
的元素,但我无法让它工作,因为我不知道如何回到树上,上下移动,检查同一元素中的其他属性:
response.then()
.assertThat()
.body("size", greaterThan(0))
.body("$.findAll (it.type.name = LPM}.status.id ", hasItem(statusId))
.body("$.findAll (it.type.name = LPM}.status.source", hasItem(sourceId))
.body("$.findAll (it.type.name = LPM}.status.price", hasItem(price));
此外,即使这有效,它也会搜索树 3 次,而实际上一次就可以完成。
我的中间比赛暂时通过了这个测试,但我想做对。我知道我可以将元素放入 List
并从那里开始计算,但为了与我们的其他示例保持一致,我宁愿不这样做,尽管我目前看不到其他选项。
我试图在文档、多个放心的教程和示例中找到我正在尝试做的事情的例子,但我没有,所以总是有可能这实际上是不可能的。如果不是,我很乐意向唐教授其背后的理论。
感谢任何帮助。
这是一种方法:
...
then().
root("find {it.type.name == '%s'}.status").
body("id", withArgs("LPM"), is(1)).
body("price", withArgs("LPM"), is(1.20f)).
body("source", withArgs("LPM"), is(172)).
body("id", withArgs("ST"), is(10));
(您显然也可以将 withArgs
提取到变量以避免重复)。
find
是 Groovy 查找与谓词 ({it.type.name == '%s'}
) 匹配的第一个元素的方法,findAll
总是 return 一个列表。
root
指示 REST Assured 使用在后续预期中使用的 "root path"(请参阅 docs)。
经验有限,放心。我们有许多测试,我通常可以在其中找到示例,或者失败 google,但是当我尝试匹配匿名数组中的元素的嵌套 属性 并验证属性时,我被卡住了上下(表亲?)。
示例JSON:
[
{
"id":1,
"type":{
"typeId":3,
"name":"LPM"
},
"status":{
"id":1,
"price":1.20,
"source":172,
"valid":0
}
},
{
"id":2,
"type":{
"typeId":2,
"name":"ST"
},
"status":{
"id":10,
"price":1.20,
"source":172,
"valid":0
}
}
]
我用的是放心,我想在列表中找到type.name
等于LPM的元素,然后验证status.price
、status.source
和status.id
只有那个元素。
当我最初开始验证响应时,数组中只能有一个项目,所以我使用的是:
response.then()
.assertThat()
.body("size", greaterThan(0))
.body("[0].type.name", equalToIgnoringCase("LPM"))
.body("[0].status.id", equalTo(statusId))
.body("[0].status.source", equalTo(sourceId))
.body("[0].status.price", equalTo(price));
然而,这不再保证有效,因为数组中可能有多个元素,并且无法保证顺序。
我已将 body 支票修改为:
response.then()
.assertThat()
.body("size", greaterThan(0))
.body("type.name", hasItem("LPM"))
.body("status.id", hasItem(statusId))
.body("status.source", hasItem(sourceId))
.body("status.price", hasItem(price));
这足以让测试通过,但这引入了 status.id
、status.source
和 status.price
具有 type.name
LPM 的元素的风险可能不正确,但这不会被检测到,因为它们将与具有 type.name
ST.
所以我希望能够找到具有 LPM 的元素,因为它是 type.name
,我可以保证只有一个,然后 status.id
,status.source
,和 status.price
,仅检查该元素,即 NOT ST 元素。
我试图修改我的 body 匹配器以找到具有我需要的 type.name
的元素,但我无法让它工作,因为我不知道如何回到树上,上下移动,检查同一元素中的其他属性:
response.then()
.assertThat()
.body("size", greaterThan(0))
.body("$.findAll (it.type.name = LPM}.status.id ", hasItem(statusId))
.body("$.findAll (it.type.name = LPM}.status.source", hasItem(sourceId))
.body("$.findAll (it.type.name = LPM}.status.price", hasItem(price));
此外,即使这有效,它也会搜索树 3 次,而实际上一次就可以完成。
我的中间比赛暂时通过了这个测试,但我想做对。我知道我可以将元素放入 List
并从那里开始计算,但为了与我们的其他示例保持一致,我宁愿不这样做,尽管我目前看不到其他选项。
我试图在文档、多个放心的教程和示例中找到我正在尝试做的事情的例子,但我没有,所以总是有可能这实际上是不可能的。如果不是,我很乐意向唐教授其背后的理论。
感谢任何帮助。
这是一种方法:
...
then().
root("find {it.type.name == '%s'}.status").
body("id", withArgs("LPM"), is(1)).
body("price", withArgs("LPM"), is(1.20f)).
body("source", withArgs("LPM"), is(172)).
body("id", withArgs("ST"), is(10));
(您显然也可以将 withArgs
提取到变量以避免重复)。
find
是 Groovy 查找与谓词 ({it.type.name == '%s'}
) 匹配的第一个元素的方法,findAll
总是 return 一个列表。
root
指示 REST Assured 使用在后续预期中使用的 "root path"(请参阅 docs)。