Flutter:使用fake_cloud_firestore测试Firestore Repository时when()桩方法未触发的问题排查
解决FakeCloudFirestore与Mockito配合时的方法打桩问题
你遇到的Bad state: No method stub was called from within when()错误,核心原因是**FakeFirebaseFirestore不是Mockito生成的mock对象**——它是一个预实现的模拟类,专门用来模拟Firestore的真实数据操作逻辑,但无法被Mockito的when()方法拦截和打桩。
正确的解决方案:用Mockito完整mock Firestore调用链
既然你要测试异常分支,完全用Mockito来mock整个Firestore调用流程会更直接。下面是修改后的测试代码:
第一步:定义Mockito的Mock类
在测试文件中添加这些mock类,用来模拟Firestore的各个层级:
import 'package:mockito/mockito.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class MockFirebaseFirestore extends Mock implements FirebaseFirestore {} class MockCollectionReference extends Mock implements CollectionReference {} class MockDocumentReference extends Mock implements DocumentReference {}
第二步:初始化测试依赖
替换原来的FakeFirebaseFirestore为Mockito的mock实例:
final mockFirestore = MockFirebaseFirestore(); final userRepository = UserRepository(mockFirestore);
第三步:修改测试代码,正确打桩异常
test('updateUser returns unexpected failure on general exception', () async { // 准备测试数据 final Map<String, dynamic> jsonMap = json.decode( fixture("user/full_domain_fuser.json"), ); final FUser fuser = FUser.fromJson(jsonMap); final userJson = UserDTO.fromDomainForUpdatingProfile(fuser).toJson(); // 构建Firestore调用链的mock final mockCollectionRef = MockCollectionReference(); final mockDocRef = MockDocumentReference(); // 打桩每个层级的调用,返回对应的mock实例 when(mockFirestore.collection(FirestoreCollections.COLLECTION_USERS)) .thenReturn(mockCollectionRef); when(mockCollectionRef.doc(fuser.id)).thenReturn(mockDocRef); // 打桩set方法抛出异常 when(mockDocRef.set(userJson, SetOptions(merge: true))) .thenThrow(Exception()); // 执行待测试方法 final result = await userRepository.updateUser(fuser); // 验证结果(注意:原来的断言写错了,要实例化具体的Failure) expect(result, const Left(UserFailure.unexpected())); // 可选:验证方法是否被正确调用过一次 verify(mockDocRef.set(userJson, SetOptions(merge: true))).called(1); });
额外注意事项
- 断言修正:你原来的
expect(result, const Left(UserFailure))是错误的,UserFailure是类,需要实例化具体的失败类型(比如UserFailure.unexpected())。 - FakeCloudFirestore的适用场景:如果你要测试正常的更新成功流程(比如验证Firestore中的数据是否正确),
fake_cloud_firestore是很好的选择;但测试异常分支时,Mockito的mock方式更灵活。
内容的提问来源于stack exchange,提问作者Donatas
相关产品推荐
相关产品推荐

