Summary
After upgrading from spring boot 2.2.8 to 2.3.1 we had failing tests.
If we throw a ResponseStatusException
in a RestController
in the corresponding test (using WebTestClient
) the body is empty (no content).
However if we test it using curl/postman etc. the body is not empty and contains the desired error message in the json field "message".
Steps to reproduce
- Checkout sample application (e.g
git clone https://github.com/WtfJoke/springwebtestclientbug.git
) - Run
SampleControllerTest
βΆοΈ π΄ - (Optional) Check out branch spring228
- (Optional) Run
SampleControllerTest
βΆοΈ βοΈ
Notes
The demo projects also contains a branch with the same code with spring boot 2.2.8 where the same tests passes (see CI).
Comment From: wilkinsona
This is the expected default behaviour in Spring Boot 2.3. Please see the relevant section of the release notes for details.
Comment From: WtfJoke
@wilkinsona Thank you for your answer and linking me to the corresponding section of the release notes. π
What I dont get, is why is the behaviour different from WebTestClient and a regular http client like curl (where the error body is delivered, even if server.error.include-message
is not defined)?
E.g why is the body included in curl and not in webtestclient?
Comment From: wilkinsona
Sorry, I missed that part of the problem. We'll need to take a closer look.
Comment From: wilkinsona
The body is not empty when using WebTestClient
. If I modify you test to the following:
@Test
fun exception() {
webTestClient.get().uri("/exception")
.exchange()
.expectStatus().isBadRequest
.expectBody()
.isEmpty()
}
It fails with the following output:
Expected empty body
> GET http://localhost:59273/exception
> WebTestClient-Request-Id: [1]
No content
< 400 BAD_REQUEST Bad Request
< Content-Type: [application/json]
< Transfer-Encoding: [chunked]
< Date: [Mon, 22 Jun 2020 12:41:20 GMT]
< Connection: [close]
{"timestamp":"2020-06-22T12:41:20.124+00:00","status":400,"error":"Bad Request","message":"","path":"/exception"}
java.lang.AssertionError: Expected empty body
As expected, the body is not empty but message
is empty. If I then reinstate your original test and add server.error.include-message=always
to application.properties
, the test passes.
Comment From: WtfJoke
Thanks for your analysis, I mistakenly took No content
for empty body. Sorry about that.
I already tested server.error.include-message=always
before and it works as expected π
Comment From: wilkinsona
Ah, I see. In the output above, No content
is for the body of the request.
Comment From: lackovic
I already tested
server.error.include-mesage=always
before and it works as expected π
I had the same error and adding that property did not fix it.
It was only after some time that I realized that an s
was missing from mesage
.
So the actual property is the following:
server.error.include-message=always
and needs to be added to test/resources/application.properties
.