How can I determine when a response path doesn't exist?

2,726 views
Skip to first unread message

Brad Wosmek

unread,
Jul 2, 2013, 11:06:09 AM7/2/13
to rest-a...@googlegroups.com
Response body:
{
    "done": true,
    "records": [
        {
            "Name": "Bob",
            "Phone": null,
            "CreatedDate": "2013-07-02T14:25:06Z",
            "Id": "0ca00000piscd1bj"
        }
    ],
    "size": 1
}

Test:
    public void invalidPathRepro() {
        given().log().all()
            .contentType("application/x-www-form-urlencoded")
            .cookie("JSESSIONID", sessionCookie)
            .param("query", "Select Name, Phone, CreatedDate from Account")
        .expect().log().all()
            .statusCode(200)
            .body("records.Name",  contains("Bob")) // Testing full match of element
            .body("records.CreatedDate", containsInAnyOrder(startsWith("20"))) // Testing partial match of element
            .body("records.Phone", containsInAnyOrder(nullValue())) // I expect the value at this path to be null
            .body("records.WouldExpectToFail", containsInAnyOrder(anything())) // This path doesn't exist, so I'd like the test to fail. 
            .body("size", equalTo(1))
        .when()
            .get("");
    }

For some tests I'd like to simply verify that a path exists in the response, but I don't care that it has a specific value.  I've found that if I provide a non-existent path as the first argument to body(), (e.g. "records.WouldExpectToFail" in the example above), the value [null] is compared in the matcher.

I've found that I can check path existence using something like this:
.body(containsString("WouldExpectToFail"))

This method isn't as precise as I'd wish and I can't mix expected body TEXT content and JSON content.  The exception below is returned when attempting to mix them:
java.lang.IllegalStateException: Currently you cannot mix body expectations that require different content types for matching.
For example XPath and full body matching requires TEXT content and JSON/XML matching requires JSON/XML/ANY mapping. You need to split conflicting matchers into two tests. Your matchers are:
Body containing expression "records.Name" must match iterable containing ["Bob"] which cannot be 'TEXT'
Body containing expression "records.CreatedDate" must match iterable over [a string starting with "20"] in any order which cannot be 'TEXT'
Body containing expression "records.Phone" must match iterable over [null] in any order which cannot be 'TEXT'
Body containing expression "records.WouldExpectToFail" must match iterable over [ANYTHING] in any order which cannot be 'TEXT'
Body must match a string containing "WouldExpectToFail" which requires 'TEXT'
Body containing expression "size" must match <1> which cannot be 'TEXT'

I've read through the RA and Hamcrest Javadocs extensively and searched for examples, but have come up empty.  I'm hoping there's an elegant solution through RA's nice DSL that I just haven't figured out yet.  Has anyone else figured this out before?

The closest I've found to an answer was in the thread: https://groups.google.com/forum/#!topic/rest-assured/CXozJ2caMis  Johan mentioned, "Generally you can check "non-existing" by using "nullValue()".", which is true, but nullValue() also matches existing paths that actually have a null value like "records.Phone" in the example above.

Thanks,

Brad

Johan Haleby

unread,
Jul 3, 2013, 1:48:55 AM7/3/13
to rest-a...@googlegroups.com
Hi, 

Well there's one way that I know of but it's not very pretty. You could do something like this: 

.. body("records.any { it.containsKey('Phone') }", is(true))
.. body("records.any { it.containsKey('Phone2') }", is(false))

Regards,
/Johan



--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Brad Wosmek

unread,
Jul 3, 2013, 8:01:00 AM7/3/13
to rest-a...@googlegroups.com
Thank you Johan,

I'll give that a try.  My first impression is that I like it better than my current solution:

List<String> allFieldsList = Arrays.asList("Phone", "Name", "CreatedDate", "Id");

String respString = resp.getBody().asString();
for (String s : allFieldsList) {
    AssertJUnit.assertTrue(s + ": field was not returned in the query response.", respString.contains("\"" + s + "\":"));
}

Regards,

Brad
Reply all
Reply to author
Forward
0 new messages