Reputation: 53
I am validating response body by checking if in every items name or panCode contains "PAN".
That's doesn't work for validating if every items name or panCode contains "PAN" and i have the error
Expected: every item is (hasProperty("name", a string containing "PAN") or hasProperty("panCode", a string containing "PAN"))
Actual: [{"id":1000000002099,"name":"","panCode":"PANPL00002101","idAttachedDu":1000000008574},{"id":1000000002100,"name":"","panCode":"PANPL00002102","idAttachedDu":1000000008574}]
response.then().assertThat().body(everyItem(
either(hasProperty("name", containsString(criteria)))
.or(hasProperty("panCode", containsString(criteria)))));
How can I validate either name or panCode in body using hamcrest ?
Upvotes: 2
Views: 1646
Reputation: 1390
The reason why your example is not working is that hasProperty(java.lang.String propertyName, Matcher<?> valueMatcher)
matcher is working with JavaBean objects, while JsonPath represents everything as a Map. Take a look at this method's description from Hamcrest's Matchers JavaDoc:
Creates a matcher that matches when the examined object has a JavaBean property with the specified name whose value satisfies the specified matcher.
When you're working with response using body(Matcher<?> matcher, Matcher<?>... additionalMatchers)
it converts response JSON to map and JavaBean matcher cannot be applied here. Instead try using matchers that work with java.util.Map
.
Here's how your example can work:
response.then().assertThat()
.body("$", everyItem(either(hasEntry(equalTo("name"), containsString(criteria)))
.or(hasEntry(equalTo("panCode"), containsString(criteria)))));
Upvotes: 0
Reputation: 3755
Since response body is straight forward json array, following approach would work.
First its better to have class representing one item of the array, Like Pan
public static class Pan
{
private long id;
private String name;
private String panCode;
private String idAttachedDu;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPanCode() {
return panCode;
}
public void setPanCode(String panCode) {
this.panCode = panCode;
}
public String getIdAttachedDu() {
return idAttachedDu;
}
public void setIdAttachedDu(String idAttachedDu) {
this.idAttachedDu = idAttachedDu;
}
}
add jackson or gson to deserialize json into this type of object (here jackson is used)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
Finally get the response, convert it to array of Pan
s then assert. (please change url as required, extra tip: use mockoon for local mock server)
@Test
void panRestAssuredTest() {
Response response = given().headers("Content-Type", ContentType.JSON, "Accept", ContentType.JSON).
when().get("http://localhost:8000/restassured").
then().contentType(ContentType.JSON).extract().response();
List<Pan> pans = response.jsonPath().getList("$", Pan.class);
assertThat(pans, everyItem(
either(hasProperty("panCode", containsString("PAN")))
.or(hasProperty("name", containsString("PAN"))))
);
}
Upvotes: 2