Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to throw an exception on an CompletableFuture.get() call?

Is there a way to have mockito throw an exception on the CompletableFuture.get() call and not just the asynchronous method?

For example, given the following (incorrect) test case:

@Test
public void whenRunnerThrows_thenReturn5xx() throws Exception {
    when(service.runAsync(any(),any())).thenThrow(new Exception(""));

    mvc.perform(post("/test")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"name\":\"test\"}"))
            .andExpect(status().is5xxServerError());
}

When service.runAsync() is called during testing, an exception is thrown, which makes sense. But when the (Spring Boot) application is run, then the same exception will only be thrown as a an ExecutionException cause on the returned CompletableFuture::get.

What is the correct way to write a test like this one so that the exception is thrown at the same time in unit testing as it is when running the application?

like image 834
jeffaudio Avatar asked Jul 09 '18 18:07

jeffaudio


1 Answers

As Sotirios pointed out, you can create a CompletableFuture and have it complete with the exception. Here's the code for reference to others:

@Test
public void whenRunnerThrows_thenReturn5xx() throws Exception {
    CompletableFuture<String> badFuture = new CompletableFuture<>();
    badFuture.completeExceptionally(new Exception(""));
    when(service.runAsync(any(),any())).thenReturn(badFuture);

    mvc.perform(post("/test")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"name\":\"test\"}"))
            .andExpect(status().is5xxServerError());
}
like image 58
jeffaudio Avatar answered Nov 15 '22 04:11

jeffaudio