Reputation: 1338
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.
Upvotes: 10
Views: 23314
Reputation: 1
Here's something that seems to work but doesn't:
.jsonPath("$.message").toString().contains("textYoureLookingFor")
It returns true whether the text is there or not.
Upvotes: 0
Reputation: 870
As of Spring Framework 5 (not sure which version) the following can be used:
.jsonPath("message")
.value(Matchers.containsString(<your_string>));
Upvotes: 6
Reputation: 133
I had the problem that my response body was plain text, not JSON and neither
.jsonPath("$[?(@ contains 'my substring')]").exists()
nor
.jsonPath("$[?(@ =~ /.*my substring.*/)]").hasJsonPath()
returned a value.
So I fetched and processed the body manually:
ResponseSpec resp = testClient.get().uri(myUrl).exchange();
resp.expectBody(String.class).consumeWith(respBody -> {
assertTrue(respBody.getResponseBody().contains("my substring"));
});
Upvotes: 1
Reputation: 1310
WebTestClient WebFlux Spring Boot 2.3.4:
wtc.post()
.uri(CREATE_ACCOUNT_URL)
.contentType(APP_MEDIA_TYPE)
.accept(APP_MEDIA_TYPE)
.bodyValue(json)
.exchange()
.expectStatus().isBadRequest()
.expectBody()
.consumeWith(this::dumpToScreen)
.jsonPath("$.timestamp").isNotEmpty()
.jsonPath("$.path").isEqualTo(CREATE_ACCOUNT_URL)
.jsonPath("$.status").isEqualTo(HttpStatus.BAD_REQUEST.value())
.jsonPath("$.error").isEqualTo(HttpStatus.BAD_REQUEST.getReasonPhrase())
.jsonPath("$.message").isEqualTo(WebExchangeBindingException.MESSAGE)
.jsonPath("$.reason").exists()
.jsonPath("$.reason.size()").isEqualTo(2)
.jsonPath("$.reason.password.size()").isEqualTo(1)
.jsonPath("$.reason.password").isEqualTo(EXC_MSG_NOT_NULL)
.jsonPath("$.reason.email.size()").isEqualTo(1)
.jsonPath("$.reason.email").isEqualTo(EXC_MSG_NOT_NULL);
// When having more than 1 message
//.jsonPath("$.reason.email").value(containsInAnyOrder(EXC_MSG_NOT_NULL, EXC_MSG_NOT_BLANK));
Upvotes: 3
Reputation: 2273
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();
Upvotes: 6
Reputation: 31267
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.
Upvotes: 9