'type 'Null' is not a subtype of type 'Future<UserCredential>'
First of all I want to emphasis that I am a beginner in flutter, and please correct me if I am mentioning something wrong. I have a task to write some unit tests with regarding to the user signin in firebase. But I fail to mock it using mockito and I keep getting some errors.
class MockFirestore extends Mock implements FirebaseFirestore {}
class MockUserCredential extends Mock implements UserCredential {}
class MockFirebaseUser extends Mock implements User {}
class MockFirebaseAuth extends Mock implements FirebaseAuth {}
void main() {
late UserAuthRemoteDataSourceImpl impl;
late MockFirebaseAuth mockAuth;
late MockFirestore mockFirestore;
final credential = MockUserCredential();
final user = MockFirebaseUser();
setUp(() {
mockAuth = MockFirebaseAuth();
mockFirestore = MockFirestore();
impl = UserAuthRemoteDataSourceImpl(mockAuth, mockFirestore);
});
test("Flutter test", () async {
when(mockAuth.signInWithEmailAndPassword(
email: "email", password: "password"))
.thenAnswer((realInvocation) async => Future.value(credential));
final result = await impl.signInUser("email", "password");
expect(result, credential);
verify(mockAuth.signInWithEmailAndPassword(
email: "email", password: "password"));
});
}
Whenever I run this test case I keep getting type Null is not a subtype of type Future<UserCredential>. I am not sure what I am doing wrong. Assistance will be really appreciated. Thanks in advance.
Solution 1:[1]
After several hours of research and dive in I found a solution. Initially, mock the above classes as mentioned in the question itself. Then for the MockFirebaseAuth override the methods you want to access from your data sources. For example, In my case it's user sign in using email and password, So what i did was,
class MockFirebaseAuth extends Mock implements FirebaseAuth {
@override
Future<UserCredential> signInWithEmailAndPassword({
required String? email,
required String? password,
}) =>
super.noSuchMethod(
Invocation.method(#signInWithEmailAndPassword, [email, password]),
returnValue: Future.value(MockUserCredential()));
}
After that stub the method using mockito
void main() {
late UserAuthRemoteDataSourceImpl authRemoteDataSourceImpl;
late MockFirebaseAuth mockAuth;
late MockFirestore mockFirestore;
late MockUserCredential mockCredential;
late MockUser mockUser;
setUp(() {
mockAuth = MockFirebaseAuth();
mockFirestore = MockFirestore();
mockCredential = MockUserCredential();
mockUser = MockUser();
authRemoteDataSourceImpl =
UserAuthRemoteDataSourceImpl(mockAuth, mockFirestore);
when(mockCredential.user).thenReturn(mockUser); // IMPORTANT
});
}
Finally write your desired test cases. Eg:
test("When valid password and emails are provided Should return a user details",
() async {
UserModel userModel = UserModel(email: "", displayName: "");
when(mockAuth.signInWithEmailAndPassword(email: any, password: any))
.thenAnswer((_) async => mockCredential);
final result =
await authRemoteDataSourceImpl.signInUser(testEmail, testPassword);
expect(result, userModel);
verify(mockAuth.signInWithEmailAndPassword(
email: testEmail, password: testPassword));
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | SVG |
