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

如何Mock FutureProvider.autodispose?Mock函数未调用问题排查

问题:Mock AutoDispose FutureProvider 时Mock函数未被调用

原始Provider实现

final provider = FutureProvider.autoDispose<Metadata>(
  (ref) async {
    final response = await ref.read(service).run();
    return response;
  },
  dependencies: [service],
  name: 'provider',
);

测试代码问题

测试中自定义了_Create抽象类和_ProviderCreate Mock类尝试覆盖Provider,但Mock的call方法始终未被触发。

原因

FutureProvider.autoDispose的overrideWith方法要求传入**AutoDisposeFutureProviderCreate<T>**类型的函数,你自定义的_Create接口和Mock类与该类型不兼容,导致覆盖逻辑不生效,Provider依然执行原始创建逻辑。

解决方案

方法1:用overrideWithValue返回预定义状态(推荐简单场景)

如果不需要依赖ref,直接返回固定的AsyncValue(成功/错误状态)即可:

test('test', () async {
  final container = ProviderContainer(
    overrides: [
      // 返回成功状态
      provider.overrideWithValue(const AsyncData(Metadata(...))),
      // 如需模拟错误,可替换为:
      // provider.overrideWithValue(AsyncError(Exception('测试错误'), StackTrace.current)),
    ],
  );
  final listener = ListenerMock<HomeScreenMetadata>();
  container.listen<HomePageMetadata>(homePageProvider, listener, fireImmediately: true);

  await container.pump();

  const homePageUnloaded = HomePageMetadata(loaded: false);
  const homePageLoaded = HomeScreenMetadata(loaded: true);

  verifyInOrder(
    [
      () => listener(null, homePageUnloaded),
      () => listener(homePageUnloaded, homePageLoaded),
    ],
  );

  verifyNoMoreInteractions(listener);
});

方法2:正确使用overrideWith传入匹配的函数类型

如果需要在Mock中使用ref,直接MockAutoDisposeFutureProviderCreate类型:

test('test', () async {
  // 直接Mock对应函数类型
  final mockCreate = mock<AutoDisposeFutureProviderCreate<Metadata>>();
  
  when(() => mockCreate(any())).thenAnswer((_) async {
    print("called");
    return Metadata(...);
  });

  final container = ProviderContainer(
    overrides: [
      provider.overrideWith(mockCreate),
    ],
  );
  final listener = ListenerMock<HomeScreenMetadata>();
  container.listen<HomePageMetadata>(homePageProvider, listener, fireImmediately: true);

  await container.pump();

  const homePageUnloaded = HomePageMetadata(loaded: false);
  const homePageLoaded = HomeScreenMetadata(loaded: true);

  verifyInOrder(
    [
      () => listener(null, homePageUnloaded),
      () => listener(homePageUnloaded, homePageLoaded),
    ],
  );

  verifyNoMoreInteractions(listener);
  // 验证Mock函数被调用
  verify(() => mockCreate(any())).called(1);
});

补充:无需Mockito的自定义逻辑写法

如果不需要Mock,直接传入匿名函数实现测试逻辑:

final container = ProviderContainer(
  overrides: [
    provider.overrideWith((ref) async {
      // 自定义测试逻辑
      await Future.delayed(const Duration(milliseconds: 10));
      return Metadata(...);
    }),
  ],
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:33:23