我想在运行集成测试时禁用@EnableAsync
。
我试图覆盖配置文件,该配置文件使用@EnableAsync
注释,并在我的测试包中使用同名的类但它不起作用。
在本主题中:Is it possible to disable Spring's @Async during integration test?
我见过:
您可以...创建测试配置或使用SyncTaskExecutor覆盖任务执行器
但我不明白该怎么做。
有什么建议吗?感谢
答案 0 :(得分:15)
您链接的主题确实提供了一个很好的解决方案。
要为测试创建SyncTaskExecutor
,请确保您实际拥有spring上下文的测试配置类。请参考Spring文档:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
在此配置类中添加一个新bean:
@Bean
@Primary
public TaskExecutor taskExecutor() {
return new SyncTaskExecutor();
}
应该这样做!
注意不要在实时配置中创建这个bean!
答案 1 :(得分:0)
您还可以在您的类中创建两个方法,一个方法中带有@Async
批注,第二个方法将具有您需要测试的所有逻辑而无需使用此批注并进行第一个方法调用第二。然后,在测试中,您将调用具有package-private
可见性的第二种方法。
例如:
@Async
public void methodAsync() {
this.method();
}
void method() {
// Your business logic here!
}
答案 2 :(得分:0)
我们最终使用了默认情况下为yourcompany.someExecutor.async
的道具true
(因此,在application.yml
中不会显示不),并且在测试中使用TestPropertySource
将其设置为false
。基于该道具,我们可以初始化SyncTaskExecutor
或一些异步版本(例如ThreadPoolTaskExecutor
)。
请注意,这还可以使用多个道具,因此很容易为每个道具禁用特定的执行器。在我们的例子中,根据上下文,我们有几个异步执行器。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {
"yourcompany.someExecutor.async=false",
})
public class SomeIntegrationTest {
// ... tests requiring async disabled
}
@Configuration
public class SomeConfig {
// ...
@Value("${yourcompany.someExecutor.async:true}")
private boolean asyncEnabled;
@Bean("someExecutor") // specific executor
public Executor algoExecutor() {
if (!asyncEnabled) {
return new SyncTaskExecutor();
}
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(THREAD_COUNT);
executor.setMaxPoolSize(THREAD_COUNT);
executor.setQueueCapacity(QUEUE_CAPACITY);
executor.setThreadNamePrefix("Some-");
executor.initialize();
return executor;
}
}