CompletableFuture的单元测试Mock

在spring项目,假设我们有一个方法

// 一个executor,和普通定义线程池一样(此处是spring自带,@Scheduled注解用到的全局线程池)
@Resource
private ThreadPoolTaskExecutor executor;

// 另一个需要装配的假定的服务
@Resource
private AnotherService anotherService;

// CompletableFuture,需要被测试的方法
public String getProductBillSummaryList(String input) {
    // 异步操作
    CompletableFuture<String> resultFuture = CompletableFuture.supplyAsync(
            () -> anotherService.someMethod(input), executor);
    
    // 等待执行完毕
    CompletableFuture.allOf(resultFuture).join();
    try {
        String s = resultFuture.get();
        System.out.println(s);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

我们对这个方法单元测试,大概率就直接写成:

@Mock
private AnotherService anotherService;

@InjectMocks
private ProductTransactionSearchServiceImpl productTransactionSearchService;

@Test
public void getProductBillSummaryList() {
    Mockito.when(anotherService.someMethod(Mockito.any())).thenReturn("mockString");
    String res = productTransactionSearchService.getProductBillSummaryList("input");
    Assert.assertNull(res);
}

这样会导致Completable的线程不运行,一直阻塞在红色箭头指示的地方:

等待线程执行完毕。然而线程并没有执行。

此时需要模拟并驱动异步线程的执行,因此需要这样写:

@Mock
private AnotherService anotherService;

// 需要增加这个executor的mock
@Mock
private ThreadPoolTaskExecutor executor;

@InjectMocks
private ProductTransactionSearchServiceImpl productTransactionSearchService;

@Test
public void getProductBillSummaryList() {
    Mockito.when(anotherService.someMethod(Mockito.any())).thenReturn("mockString");
    // 新增对异步线程里面Runnable方法的驱动
    Mockito.doAnswer(
        (InvocationOnMock invocation) -> {
            ((Runnable) invocation.getArguments()[0]).run();
            return null;
        }
    ).when(executor).execute(Mockito.any(Runnable.class));
    String res = productTransactionSearchService.getProductBillSummaryList("input");
    Assert.assertNull(res);
}

这样就mock了对Runnable方法的运行(就是执行run方法,只要有调用就run,不阻塞)

运行单测就可以正常通过了。

参考

java - CompletableFuture usability and unit test - Stack Overflow

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值