Widgetテストでは、エミュレーターや実機を使えないので、Firebaseに問い合わせるユーザー認証の機能が使えません。
なので、モックのFirebaseAuthやGoogleSignInのパッケージを使って認証系のテストをします。
https://pub.dev/packages/firebase_auth_mocks
https://pub.dev/packages/google_sign_in_mocks
FirebaseAuthとGoogleSignInのインスタンスのProviderをoverrideして、それぞれのモックのインスタンスに置き換える
Authenticator のメソッドがモック化されたので、そのメソッドを使ってテストをする
packages/skimie/test/presentation/pages/login_page/components/signup_buttons_test.dart
GoogleログインのWidgetテストを解説します。
まず始めに、setUpにて、mockUserやmockGoogleSignIn、mockFirebaseAuthのインスタンスを用意します。このときに、mockFirebaseAuthには、mockUserのインスタンスを渡しておきます。
setUp(() async {
final MockUser mockUser = MockUser(
initialDisplayName: 'skimie_test',
);
mockGoogleSignIn = MockGoogleSignIn();
mockFirebaseAuth = MockFirebaseAuth(initCurrentUser: mockUser);
await Firebase.initializeApp();
});
Widgetテストを開始するときに、対象のProviderをoverrideしてモック化します。
ここでは、Googleログインのテストをしているので、そのメソッドがあるGoogleAuthenticatorをモック化しています。
testWidgets('Googleログイン', (WidgetTester tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
googleAuthenticatorProvider.overrideWithValue(
GoogleAuthenticator(
auth: mockFirebaseAuth,
googleSignIn: mockGoogleSignIn,
),
),
],
child: const MaterialApp(
home: Material(
child: SignUpButtons(animating: false),
),
),
),
);
SignUpButtonsをタップしたときには、FirebaseAuthのsignInWithCredentialを使っているので、
モッククラス内でこのメソッドを修正します。
@override
Future<UserCredential> signInWithCredential(
AuthCredential credential,
) async {
// ログインしたプラットフォームを確認
Log.i('ログイン : ${credential.signInMethod}');
final userCredential = MockUserCredential();
// currentUserを更新
currentUser = userCredential.user;
return userCredential;
}
setUp内でcurrentUserにMockUserをセットしていましたが、このメソッドを走らせると、別のユーザーに
currentUserが置き換わる様に修正しました。
メソッドが走ったことをユーザー名が変更されていることで確認します。
// signInWithGoogleが呼ばれたことを確認
expect(loggedInCurrentUser.displayName, 'test_login_success');
参考:
https://qiita.com/mogmet/items/ade07bd842495192922d
https://github.com/atn832/firebase_auth_mocks/blob/master/test/firebase_auth_mocks_test.dart