Anup Mondal
Anup Mondal

Reputation: 41

Mono.doOnError() reactor block unit test

I have a rest controller using spring webflux and reactor, I am writing unit test for the controller. Please find below the code snippets and help me to write the unit test method to test the .doOnError() block.

I have tried to throw an exception by using Mockito

doThrow(CriticalException.class)
          .when(myService).myMethod(object);

This is my unit test:

StepVerifier.create(
Mono.just(
          webTestClient.post() 
                       .uri("/endpoint")
                       .accept(MediaType.APPLICATION_JSON) 
                      
                        
                       .body(BodyInserters.fromObject(requestJson)) //Set the body of the request to the given synchronous Object
                                            //Returns:a Mono with the response
        //Act
                       .exchange()  //Perform the exchange 
        //Assert        
                       .expectStatus().isOk() 
                       .expectBody(Agreement.class)
                       .returnResult()
                       .getResponseBody()))
                .expectNextMatches(agreementResponse -> {
                        assertNotNull(agreementResponse.getAgreementParticipant());
                        return true; 
                }) 
                .expectComplete()
                .verify();

This is my controller:

return Mono.fromCallable(() -> { 
            myService.myMethod(object);
            return object;
        }).log().subscribeOn(Schedulers.elastic())
                .map(p -> ResponseEntity.ok(p))
                .defaultIfEmpty(ResponseEntity.notFound().build())
                .doOnError(e -> { 
                    LOGGER.error(LOG_FORMAT, e.getMessage(), e.getStackTrace());                
                }); 

Mockito is not returning exception while myService.myMethod(object) is been called. Please suggest proper way to write test for .defaultIfEmpty() and .doOnError() blocks.

Upvotes: 4

Views: 8411

Answers (1)

Yasham
Yasham

Reputation: 371

Instead of throwing CriticalException.class while mocking your myService.myMethod(object) return an exception wrapped in a Mono

For eg :

Mockito.doReturn(Mono.error(Exception::new)).when(service).callableMethod();

Find the sample code snippet below

import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

class Service {

    public Mono<String> callableMethod() {

        return Mono.just("1");
    }
}

class Controller {

    private Service service;

    public Controller(Service service) {

        this.service = service;
    }

    public Mono<String> endpoint() {

        return service.callableMethod().doOnError(throwable -> {
            System.out.println("throwable = " + throwable);
        });
    }
}

public class TestClass {

    @Mock
    private Service service = Mockito.mock(Service.class);

    @Test
    public void controllerTest() {

        Mockito.doReturn(Mono.error(Exception::new)).when(service).callableMethod();

        StepVerifier.create(new Controller(service).endpoint()).verifyError();
    }
}

Upvotes: 8

Related Questions