From the below JSON response, I can verify that a root node exists the in JSONpath using this method from hamcrest library:
assertThat(json, hasJsonPath("$.tool"));
This checks that the root node called 'tool' exists.
{
"tool":
{
"jsonpath":
{
"creator":
{
"name": "Jayway Inc.",
"location":
[
"Malmo",
"San Francisco",
"Helsingborg"
]
}
}
},
"book":
[
{
"title": "Beginning JSON",
"price": 49.99
},
{
"title": "JSON at Work",
"price": 29.99
}
]
}
If I want to check the existence of the two root nodes (tool and book)using an array stored in a variable, how can this be achieved? I am not concerned about their values or the values of the sub nodes. I just want to verify that those 2 root nodes exist in the response and are valid paths.
After stringing my API response in a 'json' variable I tried something like this:
JsonPath jp = new JsonPath(json);
String[] rootNodes = {"tool", "book"};
assertThat(json, hasJsonPath(json.getString(rootNodes)));
But compiler was unhappy with the getString
method.
Is there a way to resolve this issue?
The root node operator is $
so you can just read $
into a map and that map will be keyed on your root node names.
For example:
// Approach 1
Map<String, Object> read = JsonPath.read(json, "$");
assertThat(read.size(), is(2));
assertThat(read.keySet(), hasItem("tool"));
assertThat(read.keySet(), hasItem("book"));
// Approach 2: if you want a String[] then ...
String[] rootNodeNames = read.keySet().toArray(new String[read.size()]);
assertThat(rootNodeNames, Matchers.both(arrayWithSize(2)).and(arrayContainingInAnyOrder("book", "tool")));
// Approach 3: if you want to hide it all behind the hasJsonPath() matcher
// note: each of these assertion will cause your JSON string to be parsed
// so it's more efficient to do that once and assert against the
// resulting map as I did above
assertThat(json, hasJsonPath("$", Matchers.hasKey("tool")));
assertThat(json, hasJsonPath("$", Matchers.hasKey("book")));