Search code examples
hamcrestrest-assured

JSON arrays with duplicate items with Hamcrest and RestAssured


As a follow up question for my question in Dealing arrays with hamcrest and rest assured

How can I use hamcrest with restassured so that I can test

{
    "mobilenum": "+6519829340",
    "firstname": "Allen",
    "lastname": "Edwards",
    "location": "Singapore"
    "outbound": "YES"
    "count" : 15
}, 
{
    "mobilenum": "+6519829340",
    "firstname": "Allen",
    "lastname": "Edwards",
    "location": "Singapore"
    "outbound": "NO"
    "count" : 9
}

That there exist two types of data, one containing mobilenum, firstname, etc having outbound equal to yes, and the other no.

It would be like having two objects having the same properties except the outbound property.

An answer by John, from the previous question is this:

 .root("smsentries.find { it.mobilenum == '%s' }").    
 .body("firstname", withArgs("+6519829340"), equalTo("Allen")
 .body("lastname", withArgs("+6519829340"), equalTo("Edwards").
 .body("firstname", withArgs("+12345678"), equalTo("John")
 .body("lastname", withArgs("+12345678"), equalTo("Doe").

I don't know how to add something like withArgs("Allen") and ("Edwards) .equalTo("outbound")


UPDATE

What I hope to happen is like this:

 for (Map.Entry<String,JsonElement> entry : o.entrySet()) {
        if (entry.getKey().equals("smsentries")) {
        JsonArray array = entry.getValue().getAsJsonArray();
        for (JsonElement elementJSON : array) {
            SMSEntry smsEntry = mapper.readValue(elementJSON.toString(), SMSEntry.class);
                if (smsEntry.getMobilenum().equals("+6519829340") && 
                        smsEntry.getOutbound().equals("YES")) {
                            assertThat(smsEntry.getLocation(), equalTo("Singapore"));
                            assertThat(smsEntry.getCount(), equalTo(15));
                        }
            }
        }
    }

If I have a mobile number equal to +6519829340 and is outbound, assert that the location is in Singapore and has count of 15.


Solution

  • If I understand you correctly (and that the list of users(?) is called smsentries as it was in the previous question) you could do like this:

    .root("smsentries.findAll { it.mobilenum == '%s' }").    
    .body("firstname", withArgs("+6519829340"), contains("Allen", "Allen"))
    .body("lastname", withArgs("+6519829340"), contains("Edwards", "Edwards"))
    .body("outbound", withArgs("+6519829340"), containsInAnyOrder("YES", "NO"))
    // Additional body matchers
    

    Update after clarification

    If I have a mobile number equal to +6519829340 and is outbound, assert that the location is in Singapore and has count of 15.

    You can do like this:

    .root("smsentries.find { it.mobilenum == '+6519829340' && it.outbound == 'YES'}").    
    .body("location", equalTo("Singapore"))
    .body("count", equalTo(9))