我想声明一个应该在 @Async
void 方法中抛出的异常。
以下失败,即使我已经显式添加了一个 SyncTaskExecutor
。
org.opentest4j.AssertionFailedError:预期会抛出 RuntimeException,但没有抛出任何东西。
@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");
}
}
最佳答案
我遇到了同样的问题。
bilak 的帖子提出了使用 @Component
注释声明我的自定义 AsyncUncaughtExceptionHandler
的想法。
然后,在我对 AsyncConfigurer
的自定义实现中,我注入(inject)了我的自定义 AsyncUncaughtExceptionHandler
。
在我的测试中,我在自定义 AsyncUncaughtExceptionHandler
上使用了 @MockBean
注释,因此我能够验证是否调用了 handleUncaughtException
有适当的异常(exception)情况。
代码示例:
异步异常处理程序
@Slf4j
@Component
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
log.error("Exception while executing with message: {} ", throwable.getMessage());
log.error("Exception happen in {} method ", method.getName());
}
}
自定义异步配置器
@Configuration
public class CustomAsyncConfigurer implements AsyncConfigurer {
final private AsyncExceptionHandler asyncExceptionHandler;
@Autowired
public TaskExecutorConfiguration(AsyncExceptionHandler asyncExceptionHandler) {
this.asyncExceptionHandler = asyncExceptionHandler;
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("AsyncThread::");
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return asyncExceptionHandler;
}
}
我的单元测试:
class FooServiceTest extends FooApplicationTests {
@MockBean
private AsyncExceptionHandler asyncExceptionHandler;
@Autowired
private FooService fooService;
@Test
void testCreateEnrollmentBioStoreException() throws Exception {
fooService.doBar();
ArgumentCaptor<FooException> argumentCaptor = ArgumentCaptor.forClass(FooException.class);
verify(asyncExceptionHandler, times(1)).handleUncaughtException(argumentCaptor.capture(), any(), any());
FooException exception = argumentCaptor.getValue();
assertEquals("Foo error message", exception.getMessage());
}
}
我不确定这是否是正确的方法,但我有一个变成异步的 void 方法,所以我不想仅仅为了测试而更改返回值。
关于java - 如何在@Async void 方法中断言异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67421191/