使用Mockito测试Flutter Riverpod AsyncValue时遇非Mockito对象错误
问题原因与解决方法
报错“Used on a non-mockito object”的核心原因是你的Listener<T>泛型类没有被Mockito正确识别为mock对象,通常是因为泛型类继承Mock的方式在当前Mockito版本下不兼容,或者Mockito没有正确生成call方法的mock实现。
下面是具体的解决步骤:
1. 替换自定义Listener类,直接创建函数类型的Mock
放弃自定义的Listener<T>类,直接用Mockito提供的方式创建符合签名的mock函数,避免泛型继承带来的问题:
import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:riverpod/riverpod.dart'; void main() { group('GeoData', () { test('initialization with default GeoInfo data', () { final container = ProviderContainer(); addTearDown(container.dispose); // 直接创建对应签名的mock函数 final listener = mock<void Function(AsyncValue<GeoInfo>?, AsyncValue<GeoInfo>)>(); container.listen(geoDataProvider, listener, fireImmediately: true); // 直接验证调用,不需要箭头函数包裹 verify(listener(null, const AsyncData<GeoInfo>(GeoInfo.empty()))); verifyNoMoreInteractions(listener); }); }); }
2. 若坚持使用自定义Listener类,改用Mockito代码生成
如果一定要保留自定义的Listener类,需要使用Mockito的代码生成功能(适配Mockito 5+版本):
步骤1:添加依赖到pubspec.yaml
dev_dependencies: flutter_test: sdk: flutter mockito: ^5.4.0 build_runner: ^2.4.4
步骤2:创建mock生成文件
比如创建test/mocks.dart:
import 'package:mockito/mockito.dart'; import 'package:riverpod/riverpod.dart'; // 生成泛型Listener的mock类 @GenerateMocks([], customMocks: [ MockSpec<Listener<AsyncValue<GeoInfo>>>( as: #MockGeoInfoListener, ) ]) void main() {}
步骤3:运行代码生成命令
在终端执行:
flutter pub run build_runner build
步骤4:在测试中使用生成的mock类
import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:riverpod/riverpod.dart'; import 'mocks.dart'; // 导入生成的mock文件 void main() { group('GeoData', () { test('initialization with default GeoInfo data', () { final container = ProviderContainer(); addTearDown(container.dispose); // 使用生成的mock类 final listener = MockGeoInfoListener(); container.listen(geoDataProvider, listener, fireImmediately: true); verify(() => listener(null, const AsyncData<GeoInfo>(GeoInfo.empty()))); verifyNoMoreInteractions(listener); }); }); }
3. 额外检查点
- 确保
GeoInfo类正确实现了==运算符和hashCode方法,否则AsyncData<GeoInfo>的实例对比会失败,导致验证不通过(虽然这不是当前报错的直接原因,但会引发后续问题)。 - 确认Mockito版本与Flutter/Dart版本兼容,避免版本不匹配导致的mock失效。
内容的提问来源于stack exchange,提问作者duffy
相关产品推荐
相关产品推荐

