RestAssured如何用Hamcrest校验数组嵌套属性owner的值
我明白你遇到的困扰了——你想用hasProperty来校验JSON数组里每个对象的owner属性,但总是报错,这是因为从JsonPath提取的默认对象是Map,而Hamcrest的hasProperty是用来校验JavaBean的属性(对应getter方法),不是Map的键。下面给你几种可行的解决方案,完全贴合你的需求:
方案1:直接在RestAssured的response.body中校验(最简方式)
不用提取列表,直接在response.body()里结合everyItem和hasEntry(针对Map结构的键值对校验),这样既简洁又能同时验证owner键存在且值为myself:
response.body("rows", everyItem(hasEntry("owner", is("myself"))));
这个写法和你之前用rows.owner的效果一致,但更符合你想要的“校验每个元素属性”的思路。
方案2:提取为Map列表后校验
如果需要先提取列表再做其他操作,记得把提取的类型指定为Map<String, Object>,然后用同样的everyItem(hasEntry(...)):
List<Map<String, Object>> rows = response.extract().jsonPath().getList("rows"); assertThat(rows, everyItem(hasEntry("owner", is("myself"))));
这样就不会再出现“no 'owner' in <...>”的错误,因为hasEntry是专门用来校验Map键值对的Matcher。
方案3:用POJO结合hasProperty(最优雅的长期方案)
如果你的项目里已经有对应JSON结构的POJO类,或者愿意创建一个,就可以用hasProperty了:
- 先定义Row类:
public class Row { private String uid; private String owner; // 必须要有getter方法,Hamcrest的hasProperty依赖getter public String getOwner() { return owner; } public String getUid() { return uid; } // 可选:添加构造函数、toString等 }
- 提取时指定POJO类型,再用
hasProperty校验:
List<Row> rows = response.extract().jsonPath().getList("rows", Row.class); assertThat(rows, everyItem(hasProperty("owner", is("myself"))));
这种方式最符合面向对象的编码习惯,适合长期维护的项目。
为什么之前的写法会报错?
你之前提取的List<Object>里的元素本质是LinkedHashMap(RestAssured默认把JSON对象转成Map),而hasProperty("owner")会去寻找名为owner的JavaBean属性(也就是getOwner()方法),但Map并没有这个方法,所以才会提示“no 'owner' in <...>”。
内容的提问来源于stack exchange,提问作者TheBakker

