javacompletable-futurejava.util.concurrent

Unit test CompletableFuture exceptions


It's my first post and I'm a beginner with CompletableFuture and I want to test exceptions (InterruptedException and TimeoutException) when I use CompletableFuture.get().

My code:

CompletableFuture<ClassA> futureA =
        CompletableFuture.supplyAsync(
            () -> clientA.post(language, json, a));

CompletableFuture<ClassB> futureB =
        CompletableFuture.supplyAsync(
            () -> clientB.post(language, json, b));

CompletableFuture<Void> allFuturesResult = CompletableFuture.allOf(futureA, futureB);


try {
      allFuturesResult.get(30, TimeUnit.SECONDS); //The part I want to test
    } catch (InterruptedException ie) {
      log.error("InterruptedException: ", ie);
      Thread.currentThread().interrupt();
    } catch (ExecutionException | TimeoutException e) {
      allFuturesResult.cancel(true);
    }

I test like that by returning a failedFuture but doesn't matter. No timeout is taken into account. CompletableFuture is completed normally:

@Test
  void should_test() {
    CompletableFuture completableFuture = Mockito.mock(CompletableFuture.class);
    ...
    when(completableFuture.get(anyLong(), any())).thenReturn(CompletableFuture.failedFuture(new TimeoutException("Timeout occurred")));
  }

Thanks for your help.


Solution

  • You will need to mock the clients that get called in the lambdas running in the CompletableFuture, like

    clientA = mock(Client.class);
    // this should result in an `ExecutionException` in the future
    when(clientA.post(any(), any(), any()).thenThrow(new RuntimeException());
    

    For timeout, you can just create something that blocks forever; I can't think of a way you can easily create an InterruptedException.