3
votes

I am working with:

  • Spring MVC Test
  • Hamcrest
  • JsonPath

I have the following how a response from the server:

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {
  "id" : "100",
  "nombre" : "Jesús Você",
  "apellido" : "Mão Nuñez",
  "fecha" : "1977-12-08"
}
    Forwarded URL = null
   Redirected URL = null

The following works as expected (is valid):

 .andExpect(jsonPath("$").exists())
 .andExpect(jsonPath("$", notNullValue()))
 .andExpect(jsonPath("$", isA(LinkedHashMap.class)))

 .andExpect(jsonPath("$.*").exists())
 .andExpect(jsonPath("$.*", notNullValue()))
 .andExpect(jsonPath("$.*", isA(JSONArray.class)))
 .andExpect(jsonPath("$.*", hasSize(is(4))))

I need test that ("$") is 1. Confirm exists 1 item. It to confirm again the following:

Body = {
      "id" : "100",
      "nombre" : "Jesús Você",
      "apellido" : "Mão Nuñez",
      "fecha" : "1977-12-08"
    }

I've tried:

.andExpect(jsonPath("$", hasSize(is(1))))

Observe the difference between $ and $.*, for the latter I know it counts the number of fields. But from the former I always get:

java.lang.AssertionError: JSON path "$"
Expected: a collection with size is <1>
     but: was <{id=100, nombre=Jesús Você, apellido=Mão Nuñez, fecha=1977-12-08}>
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18

'Seems' the data is not a collection, but remember that .andExpect(jsonPath("$", isA(LinkedHashMap.class))) pass. I am confused in someway.

Therefore is possible test that ("$") is 1.? If yes, how?.

I've read count members with jsonpath?

And says:

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

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

My data returned is not an array, it is a LinkedHashMap.class because if I use .andExpect(jsonPath("$").isArray()) I get:

java.lang.AssertionError: Expected an array at JSON path "$" but found: {id=100, nombre=Jesús Você, apellido=Mão Nuñez, fecha=1977-12-08}
Expected: an instance of java.util.List
     but: <{id=100, nombre=Jesús Você, apellido=Mão Nuñez, fecha=1977-12-08}> is a java.util.LinkedHashMap

BTW: .andExpect(jsonPath("$.*").isArray()) pass.

1
I need test that ("$") is 1. Confirm exists 1 item. I've re-read this a few times but stil can't understand it. What does 1 exactly mean here?Lyubomyr Shaydariv
The following Body = { "id" : "100", "nombre" : "Jesús Você", "apellido" : "Mão Nuñez", "fecha" : "1977-12-08" } is just one item with four fields. Therefore $.* represents the item with four fields. But I need to test the item (I thought $ should be enough but fails).Manuel Jordan
Hm, but what's wrong with jsonPath("$").exists() then?Lyubomyr Shaydariv
Is valid, just curios if is possible in the other way. What happens if the result returns two items. jsonPath("$").exists() should pass too but It does not care if was 1 or 2 items.Manuel Jordan
But how do you get more than two JSON items as the root at once? It should fail due to a syntax error or whatever else reason, but this must be illegal anyway.Lyubomyr Shaydariv

1 Answers

1
votes

To validate the size of a Map instead of:

.andExpect(jsonPath("$", hasSize(1)))

you should use:

.andExpect(jsonPath("$", aMapWithSize(1)))

Note: Check this link with org.hamcrest.Matchers javadoc