The RestTestClient API provides a .json(String expected) method that allows the entire JSON response to be verified via JSONAssert e.g.
restTestClient.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody()
.json("""
{
"data": [
{"id": "123", "name": "John Doe", "email": "john@example.com"}
]
}
""")
This approach is fine when verifying simple JSON responses, but it becomes unwieldy for more complex JSON responses and/or when we want to compare the JSON properties with Java object properties.
By contrast, the MockMvcTester API provides a bodyJson() method that returns a org.springframework.test.json.JsonContentAssert object that supports more fine-grained assertions, e.g.
mockMvcTester.get().uri("/persons/1")
.assertThat()
.hasStatusOk()
.bodyJson()
.extractingPath("$.data")
.asArray().singleElement()
.hasFieldOrPropertyWithValue("id", expectedUser.getId())
.hasFieldOrPropertyWithValue("name", expectedUser.getName())
.hasFieldOrPropertyWithValue("email", expectedUser.getEmail())
Proposal
Add a method toRestTestClient.BodyContentSpec that allows the response to be consumed with a JsonContentAssert, e.g.
restTestClient.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody()
.consumeWithJsonAssert((JsonContentAssert jsonContentAssert) -> {
jsonContentAssert.extractingPath("$.data")
.asArray().singleElement()
.hasFieldOrPropertyWithValue("id", expectedUser.getId())
.hasFieldOrPropertyWithValue("name", expectedUser.getName())
.hasFieldOrPropertyWithValue("email", expectedUser.getEmail())
})
Current Workaround
In the absence of this method, I create the JsonContentAssert as below:
```java restTestClient.get().uri("/persons/1") .exchange() .expectStatus().isOk() .expectBody() .consumeWith(response -> { String responseBody = new String(response.getResponseBody(), Charset.defaultCharset()); JsonContentAssert jsonContentAssert = new JsonContent(responseBody).assertThat(); jsonContentAssert.extractingPath("$.data") .asArray().singleElement() .hasFieldOrPropertyWithValue("id", expectedUser.getId()) .hasFieldOrPropertyWithValue("name", expectedUser.getName()) .hasFieldOrPropertyWithValue("email", expectedUser.getEmail()) });
Comment From: vpelikh
I'm missing the same functionality in WebTestClient. I might work on this once it becomes clear which direction to take.
Comment From: rstoyanchev
Thanks for raising this. We intend a comprehensive update as described in #35701, #35702, and #35703. We're actively working on it, and given the short time remaining, it is not open for pull requests.
Comment From: rstoyanchev
Superseded by #35701 for RestTestClient, and #35737 for WebTestClient.