Search code examples
javarest-assuredhamcrest

How to validate either value or another value in every array items in body?


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 ?


Solution

  • 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)))));