CompletableFutures { public static <T> BiConsumer<T, Throwable> forwardTo(final CompletableFuture<T> future) { return (response, throwable) -> { if (nonNull(response)) { future.complete(response); } if (nonNull(throwable)) { future.completeExceptionally(throwable); } }; } private  CompletableFutures(); static CompletableFuture<T> exceptionallyCompletedFuture(final Throwable throwable); static BiConsumer<T, Throwable> forwardTo(final CompletableFuture<T> future);  }
@Test void shouldForwardResult() { final CompletableFuture<String> future = new CompletableFuture<>(); final CompletableFuture<String> spy = new CompletableFuture<>(); future.whenComplete(forwardTo(spy)); future.complete("foo"); assertThat(spy.join(), is("foo")); }
@Test void shouldForwardException() { final CompletableFuture<String> future = new CompletableFuture<>(); final CompletableFuture<String> spy = new CompletableFuture<>(); future.whenComplete(forwardTo(spy)); future.completeExceptionally(new IllegalStateException()); final CompletionException exception = assertThrows(CompletionException.class, spy::join); assertThat(exception.getCause(), is(instanceOf(IllegalStateException.class))); }