You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Mockito验证Future完成后执行指定动作?

验证Future完成后执行动作的Mockito测试方案

你的问题核心在于当前测试只验证了两个方法都被调用过,但没校验它们的调用时机和依赖顺序——也就是action()必须在futureReturningFunction()对应的Future完成后才执行。下面是修正后的测试方案:

关键思路

要区分两种实现,我们需要手动控制Future的完成时机,分阶段验证:

  • 让mock的futureReturningFunction返回一个可手动触发完成的Completer,而不是自动完成的Future。
  • 先调用被测函数,此时Future还未完成,验证action()尚未被调用。
  • 手动完成Future后,再验证action()被调用,同时确保调用顺序符合预期。

修正后的测试代码

test('action should be called only after future completes', () {
  // GIVEN
  final completer = Completer<void>();
  // 让mock方法返回我们可控的Future
  when(mockedDependency.futureReturningFunction()).thenReturn(completer.future);

  // WHEN
  functionBeingTested();

  // THEN: 此时Future还没完成,action绝对不能被调用
  verifyNever(mockedDependency.action());
  // 先确认future方法已经被调用
  verify(mockedDependency.futureReturningFunction()).called(1);

  // 手动触发Future完成
  completer.complete();
  // 等待事件循环处理Future的回调
  return Future<void>.delayed(Duration.zero);

  // THEN: 现在Future完成了,action应该被调用
  verify(mockedDependency.action()).called(1);
});

为什么之前的测试失效?

如果你的futureReturningFunction mock返回的是一个已完成的Future(比如Mockito默认返回的空Future,或者你没指定返回值),那么正确代码里的whenComplete会在调用functionBeingTested后立刻执行,和错误代码里直接调用action()的效果完全一致——测试自然无法区分两者。

通过Completer手动控制Future的完成时机,我们就能精准验证action()的执行时机是否依赖于Future的完成。

额外:验证调用顺序(可选)

如果你还想严格校验两个方法的调用顺序,可以使用Mockito的InOrder:

test('action should be called after future completes in correct order', () {
  final completer = Completer<void>();
  when(mockedDependency.futureReturningFunction()).thenReturn(completer.future);

  functionBeingTested();
  completer.complete();
  return Future<void>.delayed(Duration.zero);

  final inOrder = inOrder(mockedDependency);
  inOrder.verify(mockedDependency).futureReturningFunction();
  inOrder.verify(mockedDependency).action();
});

内容的提问来源于stack exchange,提问作者Rod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:25:10