SpringBootTest集成@Async;SpringBootTest,Junit exclude @Async

SpringBootTest集成@Async

问题:程序中使用@Async异步执行操作,但是在Mock测试中需要调用该方法,并且需要获取异步执行之后的数据,如何保持数据一致性与测试效率。

首先肯定不能说拷贝异步方法块之后去掉@Async,生成一模一样的同步方法专门供mock 测试类使用,这样子会造成很多重复代码,维护成本极高,并且无法保证代码测试覆盖率。

第二个是我最初使用的,在mock发送请求后,Thread.sleep()强制线程休眠。这个度并不好控制,异步方法使用初衷就是暗地处理耗时长,对正常系统操作时效性无影响的method,要设置休眠时间只能往大了加,而且肯定是越加越大,并且测试类只会越来越多,导致部署时跑测试类的时间无限延长。

一直在寻找解决方法,这里必须要吐槽国产GPT,RZ文心一言,以及各种奇奇怪怪的GPT,居然凭空捏造了@DisableAsync和@ExcludeBean 各种注解,真的是搁着玩文字游戏的。

找了一晚上,总算找到个靠谱的大佬,靠着一手研究源码得出了妙招。

大佬的详细源码说明blog link

简单的说就是在测试类中import一个配置类,在我们调用异步方法时,(由于@Async并不是auto-configuration,在新开线程执行异步时才获取连接池实例),这时候我们将异步的连接池变成一个同步的线程去run,相当于配置DisableAsync。

import java.util.concurrent.Executor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.stereotype.Component;

@Component
public class DisableAsyncForTestConfig implements AsyncConfigurer {

  @Override
  public Executor getAsyncExecutor() {
    // 测试环境下立即执行异步任务
    return new org.springframework.core.task.SyncTaskExecutor();
  }
}

测试类中Import

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Import({DisableAsyncForTestConfig.class})
@SpringBootTest
class disableAsyncTest{
}

同时,SpringBootApplication启动类中,需要额外exclude DisableAsyncForTestConfig.class,保证运行程序时正常开启异步线程

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
//exclude this async configuration for enable async
@ComponentScan(excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = DisableAsyncForTestConfig.class)})
public class SpringBootApplication {
}

打完收工 —20230722 01:41 Sat.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值