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