es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Probando onErrorResume() Spring Webflux

Tengo una capa de servicio que utiliza Spring Webflux y Reactor, y estoy escribiendo pruebas unitarias para esto. Pude probar el escenario de respuesta correcta, pero no estoy seguro de cómo probar onErrorResume() utilizando StepVerifier. Además, por favor, háganme saber si hay una mejor manera de manejar excepciones en mi controlador (por ejemplo, utilizando switchIfEmpty()).

Aquí está mi método controlador:

java
public Mono<SomeType> getInfo(Integer id) {
return webClient
.get()
.uri(uriBuilder -> uriBuilder.path())
.header("", "")
.header("", "")
.header("", "")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.retrieve()
.bodyToMono(POJO.class)
.onErrorResume(ex -> {
if (ex instanceof WebFaultException)
return Mono.error(ex);
return Mono.error(new WebFaultException(ex.getMessage(), "Error en la llamada a la API", HttpStatus.INTERNAL_SERVER_ERROR));
});
}
}

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para probar el escenario onErrorResume() usando StepVerifier, se puede generar la condición de error simulando que la llamada al webClient produzca una excepción. Aquí se muestra un ejemplo de caso de prueba:

        @Test
        public void testGetInfoError() {
            when(webClient.get()).thenReturn(requestHeadersUriSpec);
    
            // Throw a custom exception to test error scenario
            RuntimeException customError = new RuntimeException("API error");
            when(requestHeadersUriSpec.retrieve()).thenThrow(customError);
    
            service.getInfo(1)
                .as(StepVerifier::create)
                .expectError(WebFaultException.class)
                .verify();
        }
    

    Este caso de prueba primero simula la llamada get() al webClient para que devuelva un requestHeadersUriSpec. Después se configura la llamada retrieve() para simular un error lanzando una RuntimeException. Finalmente, se llama al método getInfo() y se utiliza un StepVerifier para afirmar que el método onErrorResume() captura el error correctamente y devuelve una WebFaultException.

    En cuanto al manejo de excepciones en el controlador, se puede usar switchIfEmpty() como un enfoque alternativo. switchIfEmpty() es útil cuando el Mono que se está utilizando puede devolver un resultado vacío y se quiere manejar ese escenario de manera diferente. Por ejemplo, se puede querer devolver un valor predeterminado o lanzar una excepción personalizada. Aquí se muestra un ejemplo de uso de switchIfEmpty():

        public Mono<sometype> getInfo(Integer id) {
            return webClient
                    .get()
                    .uri(uriBuilder -> uriBuilder.path())
                    .header("", "")
                    .header("", "")
                    .header("", "")
                    .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                    .retrieve()
                    .bodyToMono(POJO.class)
                    .onErrorResume(ex -> {
                        if (ex instanceof WebFaultException)
                            return Mono.error(ex);
                        return Mono.error(new WebFaultException(ex.getMessage(), "Error on API Call", HttpStatus.INTERNAL_SERVER_ERROR));
                    })
                    .switchIfEmpty(Mono.error(new WebFaultException("Empty result from API", "Empty Result", HttpStatus.NOT_FOUND)));
        }
    

    En este ejemplo, switchIfEmpty() se usa para manejar el caso en que la llamada bodyToMono() devuelve un Mono vacío. Si esto sucede, se devuelve una WebFaultException personalizada con un estado NOT_FOUND.

Comments are closed.