javaspring-testreactive

WebTestClient check that jsonPath contains sub string


In MockMvc there is an ability to assert that jsonPath contains substing

.andExpect(jsonPath("$.error.message")
.value(containsString("message")))

I wonder if there a nice way to do the same for WebTestClient, the syntax is a bit different

webClient.post().uri("/test")
                .contentType(MediaType.APPLICATION_JSON)
                .body(Mono.just(MyRequest), MyRequest.class)
                .exchange()
                .expectStatus().isBadRequest()
                .expectBody()
                .jsonPath("$.message").isEqualTo("message")

But I've found only isEqualTo method that related to it.

It could be done with exctracting getBodyAsString() from WebTestClient.BodyContentSpec but it doesn't look good.


Solution

  • There is currently (as of Spring Framework 5.0.4) no support for Hamcrest matchers for use with WebTestClient.

    However, you can use a regular expression to test if a JsonPath exists where an element contains a given substring.

    For example, I just verified the following in Spring's own test suite. Note that the /persons URL returns a list of person objects (i.e., new Person("Jane"), new Person("Jason"), new Person("John")) and that the Person class has a name property.

    this.client.get().uri("/persons")
            .accept(MediaType.APPLICATION_JSON_UTF8)
            .exchange()
            .expectStatus().isOk()
            .expectBody()
            // The following determines if at least one person is returned with a
            // name containing "oh", and "John" matches that.
            .jsonPath("$[?(@.name =~ /.*oh.*/)].name").hasJsonPath();
    

    Thus, for your use case, I assume the following might work:

    .jsonPath("$[?(@.error.message =~ /.*substring.*/)].error.message").hasJsonPath()

    Another option would be to use consumeWith(...) instead of jsonPath(...) and then use Spring's JsonPathExpectationsHelper directly (which is what MockMvc uses internally).

    Please let me know what works for you.

    p.s. SPR-16574 may potentially address this shortcoming in Spring 5.x.