Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate Exception in spring-webflux WebTestClient tests?

How can I validate the actual Exception in a spring-webflux test? The following worked in the old spring-web environment, but migrating to netty and spring-webflux, the MvcResult cannot be resolved anymore (NullPointerException):

@SpringBootTest
@AutoConfigureWebTestClient
public class ApiTest {
    @Test
    public void test() throws Exception {
        webTestClient.get()
                .uri("/api?test=123")
                .exchange()
                .expectStatus().isBadRequest()
                .expectBody().consumeWith(rsp -> {
                     //throws NPE
                    Exception ex = ((MvcResult) rsp.getMockServerResult()).getResolvedException();
                    assertTrue(ex instanceof ResponseStatusException);
                });
    }
}

@RestController 
public class ApiController {
   @PostMapping("/api")
   public String test(@RequestParam String test) {
      if (test.matches("[0-9]+"))
         throw new ResponseStatusException(HttpStatus.BadRequest, "Prohibited characters");
   }   
}

How could I still validate the real exception class?

like image 623
membersound Avatar asked Dec 12 '25 04:12

membersound


1 Answers

The main purpose of the WebTestClient is to test endpoints using fluent API to verify responses. There is no magic deserialization or error handling happening but you can get access to the raw responses (status, headers, body).

In your example you will not get MvcResult or ResponseStatusException but you could get access to the raw body using rsp.getResponseBody() that would look like

{
    "timestamp": "2022-05-17T17:57:07.041+00:00",
    "path": "/api",
    "status": 400,
    "error": "Bad Request",
    "requestId": "4fa648d"
}

You could use expectBody().consumeWith(rsp -> { ... }) to get access to the request and response or expectBody(String.class).value(body -> { ... }) to get just body. As an alternative use some fluent API to validate result JSON .expectBody().json(<expected json>) or .expectBody().jsonPath() to check specific fields only.

In addition you could still deserialize body explicitly using .expectBody(Response.class).value(body -> {...}).

like image 82
Alex Avatar answered Dec 13 '25 18:12

Alex



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!