类型 'Null' 不是类型 'Future<UserCredential>' 的子类型
type 'Null' is not a subtype of type 'Future<UserCredential>'
首先强调一下,我是flutter的初学者,说的不对还请指正。我的任务是编写一些关于 firebase 中用户登录的单元测试。但是我没能使用 mockito 来模拟它,而且我不断收到一些错误。
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"));
});
}
每当我 运行 这个测试用例时,我总是得到 type Null is not a subtype of type Future 。我不确定我做错了什么。非常感谢您的帮助。提前致谢。
经过几个小时的研究和深入研究,我找到了解决方案。最初,模拟问题本身中提到的上述 类 。然后为 MockFirebaseAuth 覆盖您要从数据源访问的方法。例如,在我的例子中,用户使用电子邮件和密码登录,所以我所做的是,
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()));
}
之后使用 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
});
}
终于写出你想要的测试用例了。例如:
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));
});
首先强调一下,我是flutter的初学者,说的不对还请指正。我的任务是编写一些关于 firebase 中用户登录的单元测试。但是我没能使用 mockito 来模拟它,而且我不断收到一些错误。
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"));
});
}
每当我 运行 这个测试用例时,我总是得到 type Null is not a subtype of type Future
经过几个小时的研究和深入研究,我找到了解决方案。最初,模拟问题本身中提到的上述 类 。然后为 MockFirebaseAuth 覆盖您要从数据源访问的方法。例如,在我的例子中,用户使用电子邮件和密码登录,所以我所做的是,
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()));
}
之后使用 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
});
}
终于写出你想要的测试用例了。例如:
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));
});