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

如何修正Stream监听器内异步函数调用的单元测试验证时机问题?

解决Stream异步回调的单元测试验证问题

问题核心是Stream监听器内的updateToken是异步操作,而verify在该异步操作完成前就执行了,导致验证失败。以下是两种可靠的解决方法:

方法一:使用Completer跟踪异步操作完成

通过给mock的updateToken方法绑定一个Completer,等待其完成后再执行验证,能精准确保异步逻辑执行完毕:

test('should update notification token when refreshed', () async {
  const fakePushToken = 'token';
  final fakeStream = StreamController<String>();
  final completer = Completer<void>();

  // 模拟Stream
  when(() => liveActivityRepo.activityUpdateStream)
      .thenAnswer((_) => fakeStream.stream);
  
  // 模拟updateToken,调用时完成Completer
  when(() => userRepo.updateLiveActivityToken(token: fakePushToken))
      .thenAnswer((_) async {
    completer.complete();
  });

  useCase.run();
  fakeStream.add(fakePushToken); // 发射事件

  await completer.future; // 等待异步操作完成
  verify(() => userRepo.updateLiveActivityToken(token: fakePushToken)).called(1);
});

方法二:等待微任务队列清空

由于Stream的异步回调会被加入微任务队列,通过await Future.microtask(() {})可以让当前测试暂停,直到所有微任务执行完毕:

test('should update notification token when refreshed', () async {
  const fakePushToken = 'token';
  final fakeStream = StreamController<String>();

  when(() => liveActivityRepo.activityUpdateStream)
      .thenAnswer((_) => fakeStream.stream);

  useCase.run();
  fakeStream.add(fakePushToken);

  // 等待微任务队列执行完,确保异步回调完成
  await Future.microtask(() {});

  verify(() => userRepo.updateLiveActivityToken(token: fakePushToken)).called(1);
});

注意事项

原测试代码中存在笔误:fakeStream.add(fakeUpdate)里的fakeUpdate应改为fakePushToken,否则会导致参数不匹配,即使异步逻辑执行了,verify也会失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:57:47