使用Mockito验证Executor异步线程中方法调用的解决方案咨询
解决Mockito异步方法调用的验证问题
方案1:用Mockito自带的超时验证器
直接给验证方法加上超时参数,让测试线程等待异步任务执行完成:
Mockito.verify(messageHandler, Mockito.timeout(1000)).handleMessage(message);
timeout(1000)表示最多等待1秒,只要这1秒内方法被调用,验证就会通过。如果要确保方法至少被调用一次,可以结合atLeastOnce():
Mockito.verify(messageHandler, Mockito.timeout(1000).atLeastOnce()).handleMessage(message);
方案2:让Executor同步执行
把测试里的Executor换成同步实现,这样异步任务会直接在测试线程里执行,验证就不会有线程问题:
// 替换executor为同步执行的实例 Executor syncExecutor = Runnable::run; // 将这个syncExecutor注入到被测试的类中
之后再执行验证逻辑,就和普通同步方法验证一样了。
如果用的是ThreadPoolExecutor,也可以手动等待任务完成后再验证:
// 先关闭线程池,不再接受新任务 ((ThreadPoolExecutor) executor).shutdown(); // 等待1秒,直到所有任务执行完毕 ((ThreadPoolExecutor) executor).awaitTermination(1, TimeUnit.SECONDS); // 此时再执行验证 Mockito.verify(messageHandler).handleMessage(message);
方案3:用CountDownLatch手动同步
通过CountDownLatch阻塞测试线程,直到目标方法被调用:
// 初始化计数为1的CountDownLatch CountDownLatch latch = new CountDownLatch(1); // 给messageHandler的mock设置应答,调用handleMessage时触发计数减1 doAnswer(invocation -> { latch.countDown(); return null; }).when(messageHandler).handleMessage(any()); // 触发异步执行逻辑(即调用executor.execute的代码) // 等待最多1秒,直到latch计数归0 latch.await(1, TimeUnit.SECONDS); // 最后执行验证 Mockito.verify(messageHandler).handleMessage(message);
内容的提问来源于stack exchange,提问作者Hayk Mkhitaryan
相关产品推荐
相关产品推荐

