5

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.

Community
  • 1
  • 1
Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
  • _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 Oct 05 '16 at 16:15
  • 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 Oct 05 '16 at 16:45
  • Hm, but what's wrong with `jsonPath("$").exists()` then? – Lyubomyr Shaydariv Oct 05 '16 at 16:53
  • 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 Oct 05 '16 at 17:25
  • 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 Oct 05 '16 at 17:55
  • Yes, should fail because is not an array (I have just one item). Remember `To test size of array: jsonPath("$", hasSize(4))` pass when is an array with many items, in this case 4. – Manuel Jordan Oct 05 '16 at 17:58
  • It must be specifics of the `hasSize()` matcher which seems to accept both root arrays or root array elements expression. You can write your matcher to substitute `hasSize()`. Sorry, I'm still blind to see the rationale behind your request. :) – Lyubomyr Shaydariv Oct 05 '16 at 18:05
  • That's the point `accept both root arrays or root array ` for the latter or `root array` the `hasSize()` does not work. – Manuel Jordan Oct 05 '16 at 18:44

1 Answers1

5

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

alfonso solis
  • 61
  • 1
  • 4