我正在尝试测试一个订阅firebaseAuth侦听器的cuit,该侦听器很容易失败,可能会调用"onError";在订阅者上。
我很难嘲笑这个例外,因为订阅并不是真正的";投掷";本身,而是使用回调调用onError。
我的立方体定义:
configureUserListener(String uid) {
userSubscription = _listenToUser(uid).listen((user) async {
//Do something with the user
});
userSubscription!.onError((e) async {
await logout();
emit(
RootCubitError(state.user, e.toString()),
);
}
}
我的测试是结构化的,所以当_listenToUser被调用时,它会抛出。然而,当流失败时,实际情况并非如此。同样,它调用onError。
我的测试:
test('should logout when user listener throws error', () async {
_auth = MockFirebaseAuth(
signedIn: true,
mockUser: MockUser(uid: parent1.id, email: parent1.email),
);
var cubit = _cubit(_auth);
when(_getLoggedInChildId()).thenReturn(null);
when(_listenToUser(any)).thenThrow(Exception()); //This is wrong, as it throws an error, instead of calling onError
cubit.init();
await expectLater(
cubit.stream,
emitsInOrder(
[
isA<RootCubitError>(),
],
),
);
verify(_sharedPreferences.clear());
verify(_auth.signOut());
});
和我的流:
@override
Stream<User> user(String uid) {
return FirebaseFirestore.instance
.collection(FirestoreCollections.users)
.doc(uid)
.snapshots()
.map((doc) => UserModel.fromMap(doc.id, doc.data())); //This map can fail and call onError
}
你知道在这种情况下我如何模拟对onError的调用吗?
只有模拟类的方法才有可能。例如,在您的案例中,您可以模拟when(_auth.anyMethod(any)).thenThrow(Exception())
,因为_auth
是一个模拟类。
目前还不清楚cubit
是否是一个模拟类。如果是这样的话,你可以在Cubit中将方法_listenToUser
从private更改为public,并添加@visibleForTestign
注释来警告你不要使用它,除非在这样的测试中:
@visibleForTesting
listenToUser(String uid) {
}
然后你可以做when(cubit.listenToUser(any)).thenThrow(Exception())