I have a handler method for an endpoint, that is this one:
public Mono<ServerResponse> create(ServerRequest serverRequest) {
Validator validator = new CreateUserValidator();
Mono<UserDto> userDtoMono = serverRequest.bodyToMono(UserDto.class);
return userDtoMono.flatMap(user ->
{
Errors errors = new BeanPropertyBindingResult(user, UserDto.class.getName());
validator.validate(user, errors);
if (errors == null || errors.getAllErrors().isEmpty()) {
return userService.create(user).flatMap(aa -> ServerResponse.status(HttpStatus.CREATED)
.contentType(MediaType.APPLICATION_JSON).body(fromValue(aa))).onErrorResume(this::handleException);
} else {
Set<String> errors1 = new HashSet<String>();
errors.getAllErrors().forEach(message -> {
errors1.add(message.getDefaultMessage());
});
return handleException(new InvalidAttributesException(errors1));
}
});
}
private Mono<ServerResponse> handleException(Throwable exception) {
ErrorResponse errorResponse = new ErrorResponse();
if (exception instanceof InvalidAttributesException) {
InvalidAttributesException asd = (InvalidAttributesException) exception;
asd.getErrors().forEach(error ->
errorResponse.addMessage(messagesService.getMessage(error)));
} else {
errorResponse.addMessage(messagesService.getMessage(exception.getMessage()));
}
logger.info("Error:" + errorResponse);
return ServerResponse.status(HttpStatus.BAD_REQUEST).body(fromValue(errorResponse));
}
As you can see, if the validator fails, the method return a bad request error with a ErrorResponse as a body.
I use a WebClient in order to test it. The WebClient has a filter to get the ErrorResponse in case of a error status:
WebClient client = WebClient.builder().clientConnector(new
ReactorClientHttpConnector(HttpClient.create(ConnectionProvider.newConnection()))).filter(ExchangeFilterFunction.ofResponseProcessor(clientResponse ->
{
if (clientResponse.statusCode().isError()){
return clientResponse.bodyToMono(ErrorResponse.class).flatMap(errorResponse ->
Mono.error(new InvalidAttributesException(new HashSet<>(errorResponse.getMessages())))
);
}
return Mono.just(clientResponse);
})).baseUrl("http://localhost:8080").build();
Mono<ErrorResponse> response = (Mono<ErrorResponse>) client.post().uri(thingsEndpoint(url)).accept( MediaType.APPLICATION_JSON ).body(Mono.just(userDto),UserDto.class).ti
.exchange();
response.subscribe(as -> {
List<String> expectedMessages = new ArrayList<>();
expectedMessages.add("name is mandatory");
expectedMessages.add("email is mandatory");
assertTrue(as.getMessages().containsAll(expectedMessages));
});
But it doesn't work. When I debug the test, it seems that when the exchange() method is called returns an exception before calling the endpoint. What am I doing bad?