LoginSignup
4

More than 1 year has passed since last update.

posted at

Flutterパッケージ「permission_handler」のWidget Test

Flutterにて絶賛アプリ開発をやっています。
これで2案件目なんですが、前回はめちゃくちゃIntegration Testにハマりました。
そして今回はWidget Testと格闘中です。

プロジェクトでGoogleMapやGooglePlaceを使った時に、 Cannot enable MyLocation layer as location permissions are not granted と言うエラーが出たのがきっかけ。
「位置情報を表示するUIがあるが、パーミッション設定してないよ」 的なエラー!

StackOverFlowで調べるとパーミッション許可のダイアログをうまいこと出してくれるパッケージがあるからそれ使ったらいいよって事でした。そして使ったのが

「permission_handler」

使い方は、パッケージを読み込んで、位置表示を表示するUIへの呼び出し部分に下記を入れるだけ

if (await Permission.location.request().isGranted) {
 // UIの呼び出し
}

とっても簡単でした。
でも、Widget Testでどハマりしました。

permission_handlerのモックを作らないと画面遷移できないのでテストが通らなくなってしまいました。
permission_handlerの公式ページやリポジトリを見ても全く記載なし!!
探しに探して3日間、やっとそれっぽいのを見つけました!
そして、まぐれ(?)にもテストが通ったのでここにメモ!!

もし、間違いがあれば教えてください!よろしくお願いします。

UI側

FlatButton(
  onPressed: () async {
    // permission_handler
    if (await Permission.location.request().isGranted) {
      final result =
          await showModalBottomSheet<GoolePlaceItemList>(
              context: context,
              isScrollControlled: true,
              builder: (BuildContext context) {
                return GoogleMapSelectPlace();
              });
      print(result);
    }
  },
  color: Colors.white,
  child: const Text(
    '次の画面へ',
    style: TextStyle(
      color: Color(0xffC4C4C4),
      fontSize: 12,
    ),
  ),
),

Widget test

void main() {
  group('SampleTest', () {
    setUp(() async {
      TestWidgetsFlutterBinding.ensureInitialized();
      await AppConfigAdapter().initialize();

   /// permission_handlerのモック
   /// 
      const MethodChannel('flutter.baseflow.com/permissions/methods')
          .setMockMethodCallHandler((MethodCall methodCall) async {
        if (methodCall.method == 'requestPermissions') {
          return <dynamic, dynamic>{
            // Permission.location.request().isGranted の許可をテストの場合は 「3」
       // 「1」 は許可OK
            3: 1,
          };
        } // set initial values here if desired
      });
    });

    testWidgets(
      '次の画面へボタンをタップするとMap画面が表示される',
      (WidgetTester tester) async {
        await tester.pumpWidget(pumpWidgetWrapper(TestScreen(
          overdrivePresenter: GoogleMapPresenter(
              testUsecase: _MockTestUsecaseCompleted(),
        )));

     // デバッグ用画面表示確認
        find
            .byType(Text)
            .evaluate()
            .toList()
            .forEach((e) => print(e.toString()));

        expect(find.text('次の画面へ'), findsOneWidget);
        await tester.tap(find.text('次の画面へ'));
        await tester.pumpAndSettle(const Duration(seconds: 5));
        expect(find.byType(GoogleMapSelectPlace), findsWidgets);
      },
    );
  });
}

参考文献

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4