JsonPath config for MockMvc

JsonPath itself can be configured like this

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;

// ...

Configuration configuration = Configuration
    .builder()
    .options(Option.REQUIRE_PROPERTIES)
    .build();

JsonPath
    .using(configuration)
    .parse(someJson)
    .read("$.*.bar");

The example above enables Option.REQUIRE_PROPERTIES configuration option, so it will throw an exception if path does not exist.

How to configure the same thing for jsonPath used by MockMvc in a spring boot project?

import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

// ...

mockMvc
    .perform(get("/test"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.*.bar").isEmpty())  // How to configure this 'jsonPath'?

Update

See the following example:

Input

[
  {"animal": "cat", "meow": true},
  {"animal": "cat", "meow": true},
  {"animal": "cat", "bark": true}
]

Expression

jsonPath("$.[?(@.animal == 'cat')].meow").value(everyItem(equalTo(true))

This produces a "false positive" test result. How I could write the json path expression, as I expect this test to produce a failed result.

Upvotes: 2

Views: 417

Answers (1)

xerx593
xerx593

Reputation: 13261

No, unfortunately, we can't configure JSONPath that fine, in context of spring-test-mockmvc.

Proof (https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java#L61):

 this.jsonPath = JsonPath.compile(this.expression);

"They" use (internally) a simpler instantiation (without configuration).

(What is wrong with isEmpty(), do you need this exception?) There are also alternative matchers like:

  • doesNotExist()
  • doesNotHaveJsonPath()

If we need this fine config + exact exception, we can still:

  • Use JsonPath directly (/as a bean) to:
  • parse (e.g.) from MvcResult.getResponse().getContentAsString()
@Bean
Configuration configuration()
 return Configuration
    .builder()
    .options(Option.REQUIRE_PROPERTIES)
    .build();
}

..and then:

@Autowired
Configuration config;
// ...
  MvcResult result = mockMvc
    .perform(get("/test"))
    .andExpect(status().isOk())
    .andReturn();
  // try/expect:
  JsonPath
    .using(config)
    .parse(result.getResponse().getContentAsString())
    .read("$.*.bar"); 

Refs:

Upvotes: 1

Related Questions