poiuytrez
poiuytrez

Reputation: 22526

Test on completable future always passing

I have the following test which should always fail:

@Test
public void testCompletable() {
    CompletableFuture.completedFuture(0)
        .thenAccept(a -> {
            org.junit.Assert.assertTrue(1==0);
        });
}

And this test always succeed. How can I make this test fail correctly?

Upvotes: 6

Views: 2175

Answers (2)

Tunaki
Tunaki

Reputation: 137249

You never try to retrieve the result of the completable future.

completedFuture(0) will return a completable future that is already completed with a result of 0. The consumer added with thenAccept will be invoked and will return a new completable future. You can verify that it is called by putting a print statement in it:

CompletableFuture.completedFuture(0)
.thenAccept(a -> {
    System.out.println("thenAccept");
    org.junit.Assert.assertTrue(1==0);
});

This will print "thenAccept" in the console. However, this new completable future completes exceptionally, since Assert.assertTrue throws an exception. That doesn't mean the exception is thrown to the caller: it simply means that we now deal with a completable future that is exceptionally completed.

So it is when we try to retrieve the value that the caller will have an exception. With get(), a ExecutionException will be thrown and with join(), a CompletionException will be thrown. As such, the following

CompletableFuture.completedFuture(0)
.thenAccept(a -> {
    org.junit.Assert.assertTrue(1==0);
}).join();

will fail.

Upvotes: 7

Nicolas Filotto
Nicolas Filotto

Reputation: 45005

It could be done like this:

@Test
public void testCompletable() throws Exception {
    CompletableFuture completableFuture = CompletableFuture.completedFuture(0)
        .thenAccept(a -> Assert.fail());
    // This will fail because of Assert.fail()
    completableFuture.get();
}

Upvotes: 2

Related Questions