java - 如何在@Async void 方法中断言异常?

标签 java spring spring-boot spring-boot-test spring-async

我想声明一个应该在 @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/

相关文章:

java - 使用 serialVersionUID 还是禁止警告?

java - Java类可以是对象,对象可以是类吗?

java - 通过浏览器将音频输入到 Java/处理 Applet?

java - SSO - 中央身份验证服务 (CAS) - 用于生产?

spring-boot tomcat 只能提供不到 10,000 个连接?

java - 如何实现具有可变行高的jtable

java - Spring配置bean静态资源映射和url映射?

java - 如何链接 react 堆订户

java - RestTemplate映射页面 'Page size must not be less than one'

jsp - 长参数不存在错误