Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 658
Evgen Avatar asked Apr 15 '26 18:04

Evgen


2 Answers

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.

like image 89
Sam Brannen Avatar answered Apr 18 '26 08:04

Sam Brannen


Check out the following example for discovering how to perform rest API tests using WebTestClient:

testClient.post().uri(URL,"value")
            .header("Authorization", "Basic " + Base64Utils
                    .encodeToString((loginInner + ":" + passwordInner).getBytes(UTF_8)))
            .exchange()
            .expectStatus()
            .isEqualTo(HttpStatus.BAD_REQUEST)
            .expectBody()
            .jsonPath("$.value_A").isEqualTo("100")
            .jsonPath("$.value_B").isEqualTo("some text")
            .jsonPath("$.value_C").isNotEmpty();
like image 32
makson Avatar answered Apr 18 '26 08:04

makson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!