Affects: Spring Test 5.3.17

Trying to set an expectation on a JSON body returned by a @RestController's endpoint inside its dedicated MockMvc test fails unexpectedly when trying to match whole JSON object instead of a single property.

This is the method for reproduction

@GetMapping("/test")
  public ResponseEntity<String> testJson() {
    return new ResponseEntity<String>("{\"root\":{\"prop1\":\"1\",\"prop2\":\"2\"}}", HttpStatus.OK);
 }

And this is its test with two different expectations issued alternatively and with an explicit wrong match to let console show extracted node.

The first one was supposed to simply return the complete node

@Test
void fail_json_path() throws Exception {
  mockMvc.perform(get("/test")
    .contentType(MediaType.APPLICATION_JSON))
  .andExpect(jsonPath("$.root").value("wrong_match"));
}

but it returns null as if root node wasn't present at all

java.lang.AssertionError: JSON path "$.root" expected:<wrong_match> but was:<null>

The second one should have identical output in this case inserted as single element inside a list

@Test
void fail_json_path() throws Exception {
  mockMvc.perform(get("/test")
    .contentType(MediaType.APPLICATION_JSON))
  .andExpect(jsonPath("$..root").value("wrong_match"));
}

instead it surprisingly works almost as expected, but strips quotes and doesn't push result inside the list, and most of all turn colons : into equal signs =

JSON path "$..root" expected:<wrong_match> but was:<{prop1=1, prop2=2}>

To show what I expected as output for the first example, this is a screen from this testing app with the same context

immagine

I think the quotes stripping can be considered an implementation choice, but first result looks like a bug.

Comment From: 4javier

Being my matching object actually an instance of one of my DTO classes, I solved using the overload of the method accepting a class to which converting the parsed node. I think .value(Object expectedValue) is useful only for leaf nodes.