Title: How to validate a JSON 2D Array using Rest Assured?
Tags: java;json;rest;api;rest-assured
Question: Here is the question.
Part 1:
"people": [
"name": "John",
"address": "765 the the",
"number": "3277772345",
},
"name": "Lee",
"address": "456 no where",
"number": "509.618.0193",
},
I want to validate the number field i.e. if the number is "509.618.0193". The JSON Path to "509.618.0193" is: people[1]. number (which is inside a JSON Array).
To do this, I did the fellowing:
List<String&gt; value=
given()
.when()
.get("/person")
.then()
.extract()
.path("people.findAll{it.number=='509.618.0193}. 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": "509.618.0193",
},
{
"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&gt; 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", "509.618.0193", "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"


Here is another answer: You can always write your own custom matcher:
private static Matcher<List<List<String&gt;&gt;&gt; containsItem(String item) {
return new TypeSafeDiagnosingMatcher<List<List<String&gt;&gt;&gt;() {
@Override
protected boolean matchesSafely(List<List<String&gt;&gt; items, Description mismatchDescription) {
return items.stream().flatMap(Collection75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0stream).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&gt; Matcher<List<List<T&gt;&gt;&gt; containsItem(T item) {...}

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2017:00:10/19/17', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<java><json><rest><api><rest-assured>', 'Title': 'How to validate a JSON 2D Array using Rest Assured?', 'ViewCount': 373, 'id': 46826973, 'user_AboutMe': None, 'user_AccountId': 7414789.0, 'user_DisplayName': 'Rashed Alam', 'user_Reputation': 11.0, 'user_Views': 6.0, 'user_id': 5640993.0}}