如何测试@Async异步任务
Future<?> result = determineAsyncExecutor(specificMethod).submit( new Callable<Object>() { public Object call() throws Exception { try { Object result = invocation.proceed(); if (result instanceof Future) { return ((Future<?>) result).get(); } } catch (Throwable ex) { ReflectionUtils.rethrowException(ex); } return null; } });
即把当前任务的调用提交给线程池,很简单。
?
?
1、测试无事务的异步任务
这个相对来说比较简单:
1.1、设置任务的返回值为Future:?
public Future sendSystemMessage(Long[] receiverIds, Message message);
?
1.2、调用future.get();等待任务结束。?
Future future = messageApi.sendSystemMessage(userIds, message); future.get();
?
?这个很简单。
?
2、测试带事务的异步任务
因为是带事务的,所以异步任务肯定要启动一个线程来执行任务,所以无法在主线程回滚,造成数据会commit到数据库,这在集成测试时肯定是不行的;解决方案是移除异步任务:
?
2.1、使用spring profile,在测试环境下不执行<task:annotation-driven>即可。
?
2.2、使用我提供的工具类,在测试时移除异步支持即可:?
//移除异步支持 if(AopProxyUtils.isAsync(messageApi)) { AopProxyUtils.removeAsync(messageApi); }
?
测试类可以参考MessageApiServiceIT.java?
工具类下载?AopProxyUtils.java
?
3、包级别测试?
@Asyncpublic void sendSystemMessage() { sendSystemMessageInner();}void sendSystemMessageInner() { //测试时测试这个方法即可}
?这样测试时测试这个包级别的sendSystemMessageInner方法即可
?
?
?其实更好的做法是spring内部提供支持,支持这样异步调用的测试。
1 楼 7454103 11 分钟前 引用