Problem with testing for equality - JSON path doesn't match?

13,541 views
Skip to first unread message

Sonni

unread,
May 1, 2012, 5:59:01 PM5/1/12
to REST assured
Hi guys.

I've just started using RestAssured and I've got a problem matching
strings for equality when using the following code

expect().body("results.Line3", equalTo("[Whakatane]")).when().get("/
addressSearch?q=Whakatane");

This should result in a pass, but for some reason the the Test fails?

As you can see from the output, the string being compared are
identical. It still fails even if I use containsString() instead of
equalTo()

java.lang.AssertionError: JSON path results.Line3 doesn't match.
Expected: [Whakatane]
Actual: [Whakatane]

It works fine if I use JsonPath instead:

String json = get("/addressSearch?q=Whakatane").asString();
JsonPath jsonPath = new JsonPath(json).setRoot("results");

assertThat(jsonPath.getString("Line3"), equalTo("[Whakatane]"));

I'm using RestAssured with TestNG

If any of you have had a similar problem I would like to know.

Johan Haleby

unread,
May 2, 2012, 2:08:39 AM5/2/12
to rest-a...@googlegroups.com
I think the actual value is an array with one element, "Whakatane".  So you should use ..body("results.Line3", hasItem("Whakatane")). .. 

The "Actual" error message is generated by Hamcrest itself and I agree that they can be hard to understand sometimes. 

/Johan

Sonni Nielsen

unread,
May 2, 2012, 5:06:25 PM5/2/12
to rest-a...@googlegroups.com
"I think the actual value is an array with one element, "Whakatane"" - you are absolutely correct and hasItem() works like a charm :)

I just don't understand why the value "Whakatane" is being wrapped in an array, should just be a simple String, as in the JSON send from the service?

/Sonni

Johan Haleby

unread,
May 3, 2012, 2:16:06 AM5/3/12
to rest-a...@googlegroups.com
Can you supply the JSON that you're trying to parse?

/Johan

Johan Haleby

unread,
Jan 25, 2013, 2:07:55 AM1/25/13
to rest-a...@googlegroups.com
Hi, 

I think you need to learn Hamcrest first off all but I agree that's not always intuitive, especially when you're using Rest Assured when the value return by "body" is not statically typed. It would be a good idea to write something down on the web-page documentation, perhaps you want to help out with this?  

In order to help you I need to see the JSON document and what parts of it you want to validate. 

Regards,
/Johan

On Thu, Jan 24, 2013 at 6:44 PM, <scott....@frontgatetickets.com> wrote:
I'm new to Rest Assured and have been having trouble with a number of tests like this.
It is not clear what matchers I need to use for which tasks.  So far I've been finding a lot of things that _don't_ work before I find a method that does.

Things I am trying to do:
  1. Verify the body has a specified label/value
     Naive solution.  expect().body("id",equalsTo("text"))   ** FAILS
     Working    List<String> check = new ArrayList<String>(); check.add("text"); expect().body("id",equalsTo(check));
  2. Verify the body has a label present with a string.
     Naive solution:  expect().body("id",isA(String.class))   ** FAILS
  3. Verify the body does NOT have a specified label.
     Naive solution:  expect().body("missing",empty())  ** Fails

I really need either a list of matchers that work with specified JSON body values, or details on how to create them.
If I missed this somewhere, I'd love someone to tell me where to go.
--
 
 

scott....@frontgatetickets.com

unread,
Jan 25, 2013, 4:02:46 PM1/25/13
to rest-a...@googlegroups.com
If it makes things work better, I'd be happy to.

Here is the JSON being sent to the code:
{
  • "uid": "51015ad9cc145",
  • "expires": "2013-01-24 10:06:29",
  • "errors": [
    • 2330
    ],
  • "items": [
    • {
      • "id": "testlabelone",
      • "title": "test site - Test Label One (DEV)",
      • "features": {
        • "storedCard": false,
        • "standbyPage": false,
        • "requireAccount": false,
        • "captcha": 2
        },
      • "locale": {
        • "default": "en_US.utf8",
        • "locales": [
          • "en_US.utf8",
          • "fr_CA.utf8",
          • "en_GB.utf8"
          ]
        },
      • "goog": {
        • "id": "2342342",
        • "urchinLabel": "label-abc",
        • "urchinUA": "UA-32253326-3"
        },
      • "related": [
        • {
          • "id": "ywjj33kf3d",
          • "title": "Basic Password Tests - GA"
          },
        • {
          • "id": "fai60k0729",
          • "title": "Bulk Buying"
          }
        ]
      }
    ]
}

Starting out, I wanted to verify the parts of the Json are being sent as expected.   Since the number of terms and possible values are still subject to change, I was keeping the tests as simple as I could.

I've been looking at the HamCrest java-docs, but they don't always help.  With no idea which tests apply to JSON and which ones don't, it is something of a minefield.

So far the only real things I've gotten to work are string equality tests and test for string.  Getting there has been very painful though.

Success:
  • body("uid",startsWith(""))
    Will succeed only when the the parameter is a string.

Fails:

  • body("uid",isA(String.class))
  • body("uid",hasItem(String.class))
  • body("",hasItem("uid"))
  • ...

Tests that I want to have working:

  • Test for existence.    Is the label found with any value associated with it in the json?
    • empty()  : doesn't work - error
    • notNullValue()  : doesn't work - _always_ true, even when key value isn't there.
    • "non-existent.size()"  is(0) : doesn't work - _always_ returns 1
If' you'd like to email me I'd be happy to work on a google doc for things that do or do not work.


Johan Haleby

unread,
Jan 28, 2013, 2:17:53 AM1/28/13
to rest-a...@googlegroups.com
Perhaps "uid" is a CharSequence? Never tried this.
  • body("uid",hasItem(String.class))
Doesn't work since hasItem require an iterable.. See hamcrest Javadoc: 

Creates a matcher for Iterables that only matches when a single pass over the examined Iterable yields at least one item that is matched by the specified itemMatcher. Whilst matching, the traversal of the examined Iterable will stop as soon as a matching item is found.
For example:
assertThat(Arrays.asList("foo", "bar"), hasItem(startsWith("ba")))
 
  • body("",hasItem("uid"))
See ab 
  • ...

Tests that I want to have working:

  • Test for existence.    Is the label found with any value associated with it in the json?
    • empty()  : doesn't work - error
    • notNullValue()  : doesn't work - _always_ true, even when key value isn't there.
    • "non-existent.size()"  is(0) : doesn't work - _always_ returns 1
Can you give me a real example? 

--
 
 

scott....@frontgatetickets.com

unread,
Jan 28, 2013, 11:29:23 AM1/28/13
to rest-a...@googlegroups.com
{   "uid": "51015ad9cc145",
Going through a set of tests for this JSON.  Items with a ????? are the ones I have no idea how to specify yet.  The string check seems hackish, but works.

expect.
  statusCode(200).
  body("uid",startsWith("")).
  body("expires",startsWith("")).
  body("errors", ?????).   // Want to verify a list of errors was there and any errors present are integers and not strings.
  body("items", ?????).   // Want to verify a list of items was there.  Should be at least 3 included: id, title, features.
  rootPath("items").
  body("id", hasItem( siteName) ).  // siteName is a string which was used to get this particular JSON. 
  body("title", startsWith("")).
  body("features", ?????). // Want to verify a list of features was present.
  body("locale", ?????). // Want to verify locale definitions was present.
  body("goog", ?????). // Want to verify a list of google definitions was present.
  body("related", ?????). // Want to verify a list of related lookups was present.
  rootPath("items.features").
  body("storedCard", ?????). // Want to verify result is boolean.
  body("standbyPage", ?????). // Want to verify result is boolean.
  body("requireAccount", ?????). // Want to verify result is boolean.
  body("captcha", ?????). // Want to verify result is integer.
  rootPath("items.locale").
  body("default", startsWith("")).
  body("locales", ?????).  // Want to verify at least one locale was present, but could be any number.
  rootPath("items.goog").
  body("id", startsWith("")).
  body("urchinLabel, startsWith("")).
  body("urchinUA", startsWith("")).
  rootPath("items.related").
  body( ????? ).   // Want to verify at least one related item is present and that the related items contain an id and title.
  body("badTest", ?????).     // Want to verify there was nothing here called badTest,  If badTest were present, this test would fail.
when().
get("/label");

Since the schema for this is still in flux, I need these test to verify if I actually have the kind of data I need in order to run the rest of the tests.

scott....@frontgatetickets.com

unread,
Jan 28, 2013, 12:21:14 PM1/28/13
to rest-a...@googlegroups.com
Found part of what was screwing me up.   JsonPath was trying to help me out, and this caused issues.  The JSON here has a singleton collection so anytime I was trying to check a value it was giving me a collection containing the value instead of the one value to be returned.

      expect().

           statusCode(200).
           body("uid",startsWith("")).
           body("expires",startsWith("20")).
           body("errors[0]",greaterThan(0)).
           body("items[0].size()",is(greaterThan(3))).
           rootPath("items[0]").

           body("title", startsWith("")).

This seems to work..  Still trying to figure out how to check for the non-existence of something, but I think I'm on the right track now.

Johan Haleby

unread,
Jan 29, 2013, 2:10:44 AM1/29/13
to rest-a...@googlegroups.com
Generally you can check "non-existing" by using "nullValue()".

/Johan
Reply all
Reply to author
Forward
0 new messages