Search code examples
javaasynchronousjunitmockito

How add assertion on Completablefuture<boolean> Junit Mockito


I have a Service called asynEvaluaEstadoSiniestro that return true or false, and some repositories that are mocked in my test.

@Service
@Slf4j
public class AsynEvaluaEstadoSiniestroImpl implements AsynEvaluaEstadoSiniestro {

  @Async("myExecutor")
  public CompletableFuture<Boolean> getEvaluacionEstadoSiniestro(DocumentRequest request) throws BusinessException {
  //do some persistances operations in repositories and return fooResult as true or false;|

  return CompletableFuture.completedFuture(fooResult);
  }
}
@InjectMocks
AsynEvaluaEstadoSiniestroImpl asynEvaluaEstadoSiniestro;

@Test
@DisplayName("Async process (1)")
void insertarSolicitudTest() throws BusinessException {
   //some when repositories functions needed for testing

CompletableFuture<Boolean> cf = asynEvaluaEstadoSiniestro.getEvaluacionEstadoSiniestro(documentRequest());
        cf.isDone();
}

when i execute sonaqube coverity it say:
Add at least one assertion to this test case.

How can i add a assertion to this test???

i hope to add a assertion to this test.


Solution

  • Every decent test case has these steps:

    1. [Given] - Create input (e.g. a DocumentRequest instance)
    2. [When] - Make some modification(s) (e.g the service call)
    3. [Then] - Check correctness of the result obtained (assertions)

    Unit testing asynchronous methods is not so hard what is seems. Fortunately there are a lot of good library to help. One of popular library is Awaitility

    If you use Maven as build tool, just add this dependency to pom.xml

    <dependency>
        <groupId>org.awaitility</groupId>
        <artifactId>awaitility</artifactId>
        <version>4.2.0</version>
        <scope>test</scope>
    </dependency>
    

    For demonstration I made a sample service:

    public class FutureService {
        private final Executor executor = CompletableFuture.delayedExecutor(5L, TimeUnit.SECONDS);
    
        public CompletableFuture<Boolean> negate(boolean input) {
            return CompletableFuture.supplyAsync(() -> !input, executor);
        }
    }
    

    The negate method returns CompletableFuture<Boolean> which waits for 5 seconds before completition. It is just for the demonstration.

    The test for this service is something like this.

    class FutureTest {
    
        private final FutureService futureService = new FutureService();
    
        @Test
        void futureTest() throws ExecutionException, InterruptedException {
            // given (call service)
            CompletableFuture<Boolean> future = futureService.negate(true);
            // when (wait until the CompletableFuture will be done but at most 10 seconds
            Awaitility.await().atMost(Duration.ofSeconds(10L)).until(future::isDone);
            // then (in this case the returned boolean value should be false)
            Assertions.assertFalse(future.get());
        }
    }