如何在RestAssured与Hamcrest中比较两个JSON字段?
RestAssured中比较JSON响应内两个字段的优雅实现
需求说明
使用RestAssured+Hamcrest做API功能测试时,需要比较JSON响应里两个不同字段的数值大小,比如验证示例响应中第一个对象的age小于第二个对象的age:
示例JSON响应:
[ { "name": "Foo", "age": 25 }, { "name": "Bar", "age": 30 } ]
你尝试的示意性无效代码:
given() .when() .get("/my-endpoint") .then() .body("[0].age", lessThan("[1].age")); // 无效代码,仅用于表达需求
可行的优雅实现方案
方案1:先提取字段再断言(最直观)
通过extract()方法先把两个字段的值提取到变量中,再用Hamcrest断言做比较:
Response response = given() .when() .get("/my-endpoint"); int fooAge = response.jsonPath().getInt("[0].age"); int barAge = response.jsonPath().getInt("[1].age"); assertThat(fooAge, lessThan(barAge));
方案2:使用ResponseAwareMatcher(链式调用风格)
如果想保持RestAssured的链式调用风格,可以用ResponseAwareMatcher,Java 8+支持Lambda简化写法:
given() .when() .get("/my-endpoint") .then() .body( resp -> resp.jsonPath().getInt("[0].age"), lessThan(resp -> resp.jsonPath().getInt("[1].age")) );
方案3:JSONPath表达式直接比较(更简洁)
利用JSONPath的表达式能力,直接在断言中验证字段比较的结果是否为true:
given() .when() .get("/my-endpoint") .then() .body("[0].age < [1].age", is(true));
如果响应结构更复杂,还可以结合JSONPath的筛选逻辑,比如通过name定位对象:
given() .when() .get("/my-endpoint") .then() .body("find { it.name == 'Foo' }.age < find { it.name == 'Bar' }.age", is(true));
内容的提问来源于stack exchange,提问作者João Pedro Schmitt
相关产品推荐
相关产品推荐

