@Test
public void testExceptionally() throws Throwable {

    TestContext ctx = new TestContext(1, TestContext.DEFAULT_WAIT_DURATION);
    AtomicInteger invocations = new AtomicInteger();
    DeferredResult<Integer> original = new DeferredResult<>();
    int recoverValue = 5;
    DeferredResult<Integer> result = original
            .exceptionally(ex -> {
                Assert.assertNotNull(ex);
                Assert.assertEquals(TestException.class, ex.getClass());
                invocations.incrementAndGet();
                return recoverValue;
            })
            .thenApply(x -> x + 1);
    result.whenComplete(ctx.getCompletionDeferred());
    runAfter(10, () -> original.fail(new TestException()));
    ctx.await();
    Assert.assertEquals(1, invocations.get());
    Assert.assertEquals(recoverValue + 1, result.getNow(exceptionSupplier()).intValue());
}