Count members with jsonpath?

Is it possible to count the number of members using JsonPath?

Using spring mvc test I am testing a controller that generates

{"foo": "oof", "bar": "rab"} 

from

 standaloneSetup(new FooController(fooService)).build() .perform(get("/something").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(jsonPath("$.foo").value("oof")) .andExpect(jsonPath("$.bar").value("rab")); 

I would like to make sure that there are no other members in the generated json. Hope counting them using jsonPath. Is it possible? Alternative solutions are also welcome.

+79
java spring spring-test-mvc testing jsonpath
Dec 6
source share
5 answers

To check the size of the array : jsonPath("$", hasSize(4))

To count the members of an object : jsonPath("$.*", hasSize(4))




Those. to verify that the API returns an array of 4 elements:

Allowed Value: [1,2,3,4]

 mockMvc.perform(get(API_URL)) .andExpect(jsonPath("$", hasSize(4))); 



to verify that the API returns an object containing 2 members:

valid value: {"foo": "oof", "bar": "rab"}

 mockMvc.perform(get(API_URL)) .andExpect(jsonPath("$.*", hasSize(2))); 



I am using Hamcrest version 1.3 and Spring Test 3.2.5.RELEASE

hasSize (int) Javadoc

Note: you need to include the dependency on the hamcrest library and import static org.hamcrest.Matchers.*; so that hasSize () works.

+174
Dec 10 '13 at 15:52
source share
Today I do this. It does not seem to be implemented in the statements available. However, there is a way to pass an org.hamcrest.Matcher object . With this, you can do something like the following:
 final int count = 4; // expected count jsonPath("$").value(new BaseMatcher() { @Override public boolean matches(Object obj) { return obj instanceof JSONObject && ((JSONObject) obj).size() == count; } @Override public void describeTo(Description description) { // nothing for now } }) 
+4
Dec 28 '12 at 23:33
source share

We can use JsonPath functions such as size() or length() , for example:

 @Test public void givenJson_whenGetLengthWithJsonPath_thenGetLength() { String jsonString = "{'username':'jhon.user','email':'jhon@company.com','age':'28'}"; int length = JsonPath .parse(jsonString) .read("$.length()"); assertThat(length).isEqualTo(3); } 

Or just net.minidev.json.JSONObject and get the size:

 @Test public void givenJson_whenParseObject_thenGetSize() { String jsonString = "{'username':'jhon.user','email':'jhon@company.com','age':'28'}"; JSONObject jsonObject = (JSONObject) JSONValue.parse(jsonString); assertThat(jsonObject) .size() .isEqualTo(3); } 

Indeed, the second approach looks better than the first. I did a JMH performance test and I got the following results:

 | Benchmark | Mode | Cnt | Score | Error | Units | |-------------------------------------------------|-------|-----|-------------|--------------|-------| | JsonPathBenchmark.benchmarkJSONObjectParse | thrpt | 5 | 3241471.044 | ±1718855.506 | ops/s | | JsonPathBenchmark.benchmarkJsonPathObjectLength | thrpt | 5 | 1680492.243 | ±132492.697 | ops/s | 

Sample code can be found here .

+3
Aug 6 '18 at 17:08
source share

if you don't have com.jayway.jsonassert.JsonAssert in your class path (which was with me), testing in the following way could be a possible workaround:

 assertEquals(expectedLength, ((net.minidev.json.JSONArray)parsedContent.read("$")).size()); 

[note: i assumed json content is always an array]

0
Nov 27 '15 at 20:55
source share

You can also use methods inside jsonpath, so instead

 mockMvc.perform(get(API_URL)) .andExpect(jsonPath("$.*", hasSize(2))); 

you can do

 mockMvc.perform(get(API_URL)) .andExpect(jsonPath("$.length()", is(2))); 
0
Nov 22 '18 at
source share



All Articles