LoginSignup
4
3

More than 3 years have passed since last update.

HTTP通信するWidgetをテストする(Flutter)

Posted at

ここ最近、Flutterを使ったクロスプラットフォームのアプリを作ろうドキュメントを片手にと勉強しています。その中でハマった、HTTP通信が含まれるWidgetのテスト方法について書き残します。最終的には以下のコードでテストが成功します。

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/testing.dart';
import 'package:http/http.dart';

class Test extends StatelessWidget {
  Client client = Client();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FutureBuilder(
        future: getWord(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (!snapshot.hasData) return CircularProgressIndicator();
          return Text(snapshot.data);
        }
      ),
    );
  }

  Future<String> getWord() async {
    final response = await client.get('http://example.com');
    return response.body;
  }
}

void main() {
  testWidgets('http mock', (WidgetTester tester) async {
    final mockClient = MockClient((_) async => Response('Hello World', 200));
    final test = Test();
    test.client = mockClient;

    await tester.pumpWidget(test);
    await tester.pumpAndSettle();
    expect(find.text('Hello World'), findsOneWidget);
  });
}

やっていることはHTTPクライアントをモックに差し替えてからテストする、これだけです。因みにパッケージは次の通りです。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  http: ^0.12.0+2

dev_dependencies:
  flutter_test:
    sdk: flutter
  mockito: ^4.1.0

それでは、順を追って説明していきます。

Widgetの作成

まずはテスト対象のWidgetを作成します。APIからのレスポンスを表示するだけのWidgetです。レスポンスを待ってからWidgetをビルドしたかったため、FutureBuilderを使用しています。このclientの中身をモッククライアントに差し替えることが今回の肝です。

class Test extends StatelessWidget {
  Client client = Client();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FutureBuilder(
        future: getWord(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (!snapshot.hasData) return CircularProgressIndicator();
          return Text(snapshot.data);
        }
      ),
    );
  }

  Future<String> getWord() async {
    final response = await client.get('http://example.com');
    return response.body;
  }
}

モッククライアントの作成

Clientを差し替えるためのモックを作成します。httpパッケージに用意されているモック作成用のMockClientクラスを利用します。ここでは、MockClientのレスポンスが'Hello World'と200ステータスを返すように設定しています。今回は、単純にレスポンスの表示するだけですが、テストの内容によってはJSONを返すようにしたり、目的に合わせてレスポンスを設定することができます。

final mockClient = MockClient((_) async => Response('Hello World', 200));

テストの実行

ここまでで、Widgetとモッククライアントができました。あとはテストを実行するだけです。Testウィジェトのインスタンスを生成して、インスタンスのclientの中身をmockClientに差し替えます。最後にtester.pumpWidgetでWidgetをビルドし、tester.pumpAndSettleでFutureBuilderが生成する「Hello World」が表示されるのを待つことでテストが成功します。

testWidgets('print test', (WidgetTester tester) async {
  final mockClient = MockClient((_) async => Response('Hello World', 200));
  final test = Test();
  test.client = mockClient;

  await tester.pumpWidget(test);
  await tester.pumpAndSettle();
  expect(find.text('Hello World'), findsOneWidget);
});

以上が、HTTP通信するWidgetのテスト方法についての記事でした。お役に立てたら幸いです!

4
3
0

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
  3. You can use dark theme
What you can do with signing up
4
3