如何使用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
相关产品推荐
相关产品推荐

