1

Here is the question.

Part 1:

{
  "people": [
    {
      "name": "John",
      "address": "765 the the",
      "number": "3277772345",
    },
    {
      "name": "Lee",
      "address": "456 no where",
       "number": "7189875432",
    },  
  ]
}

I want to validate the number field i.e. if the number is "7189875432". The JSON Path to "7189875432" is: people[1]. number (which is inside a JSON Array).

To do this, I did the fellowing:

List<String> value=
given()
.when()
.get("/person")
.then()
.extract()
.path("people.findAll{it.number=='7189875432}. number");
 If (value.isEmpty)
            assert.fail(); 

This test will pass. Basically, if the value is there it will return a list of that value. This I understand. But now let's says I have a JSON such as:

Part 2

{
  "people": [
    {
      "name": "John",
      "address": "765 the the",
      "phoneno": [
        {
          "number": "3277772345",

        },
        {
          "number": "654787654",

        },

      ]
    },
    {
      "name": "Lee",
      "address": "456 no where",
      "phoneno": [
        {
          "number": "7189875432",

        },
        {
          "number": "8976542234",

        },
        {
          "number": "987654321",

        },

      ]
    },

  ]
}

Now I want to validate if the phone number "987654321" is in the JSON. The JSON Path: people[1].phoneno[2].number

List<String> value=
given()
.when()
.get("/person")
.then()
.extract()
.path("people.phoneno.findAll{it.number=='987654321'}. number");
 If (value.isEmpty)
            assert.fail();

This test will fail because it will return an empty string.

If I hard code the path like:

.path("people[1].phoneno.findAll{it.number=='987654321'}. number");
 If (value.isEmpty)
            assert.fail(); // this test will pass

Also if I so do something like this

 .path("people.phoneno. number");
I would get a list such as [["987654321", "3277772345", "7189875432", "8976542234"]] 

with a list of all number in the JSON.

So my question is how can we validate a JSON path that has an array inside another array? I do not want to hardcode anything.

Note: The only information available is the number i.e "987654321"

1 Answer 1

1

You can always write your own custom matcher:

private static Matcher<List<List<String>>> containsItem(String item) {
    return new TypeSafeDiagnosingMatcher<List<List<String>>>() {
      @Override
      protected boolean matchesSafely(List<List<String>> items, Description mismatchDescription) {
        return items.stream().flatMap(Collection::stream).collect(toList()).contains(item);
      }

      @Override
      public void describeTo(Description description) {
        description.appendText(
            String.format("(a two-dimensional collection containing \"%s\")", item));
      }
    };
  }

And then use this matcher:

given()
.when()
.get("/person")
.then()
.body("people.phoneno.number", containsItem("987654321"));

To make this matcher even more reusable, make input type generic:
private static <T> Matcher<List<List<T>>> containsItem(T item) {...}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.