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

