I want to assert an exception that should be thrown within an @Async
void method.
The following fails, even though I already add a SyncTaskExecutor
explicit.
org.opentest4j.AssertionFailedError: Expected RuntimeException to be thrown, but nothing was thrown.
@TestConfiguration
public class SyncTaskExecutorTestConfiguration {
@Bean
@Primary
public TaskExecutor asyncExecutor() {
return new SyncTaskExecutor();
}
}
@SpringBootTest
@Import(SyncTaskExecutorTestConfiguration.class)
public class MyTest {
@Test
public void test() {
assertThrows(RuntimeException.class, () -> service.run());
}
}
@Service
@Async //also @EnableAsync existing on @Configuration class
public class AsyncService {
public void run() {
//of course real world is more complex with multiple sub calls here
throw new RuntimeException("junit test");
}
}
Since the
@Async
method get executed asynchronously by a thread fromasyncExecutor
and it is terminated due toRuntimeException
which doesn't have any impact on Main thread, the actuallyMain-Test
thread competes successfully with the rest of flow once after it trigger the async call. So i will recommend to use the CompletableFuture to hold the reference of Async process always even it's required or not and truthfully will help in test casesSo in the test you can wait for
Async
thread to complete assert the cause from ExecutionException, Since theget
method throwsExecutionException
if this future completed exceptionallyOne more note you can refer link for asserting wrapped exceptions