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.