エキサイト株式会社の高野です。
弊社では最近Flutterでテストを書き始めました。state_notifierとfreezedを用いたプロジェクトをどうやってテストしようか考えていた所Mockitoを見つけ、よさそうでしたので書いてみたコードの流れの紹介になります。
各バージョン
Flutter: 2.0.6
iOS: 14.5
Android: 11.0
使用ライブラリ
実装
僕が今開発しているローリエプレスにおける最も重要たるロジックはAPIから受け取ったものをView側に流してあげることです。
プロジェクト自体は、state_notifierとfreezedを用いて実装していますのでrepositoryから受け取ったものをstateに渡せているかをテストしていきます。
@GenerateMocks([RepositoryImpl]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); final _mockRepositoryImpl = MockRepositoryImpl(); final controller = Controller( controller: controller, ); }
以上のようにRepositoryをMockitoを用いてモック化し、Controllerをイニシャライズします。
test('記事を20件取得する', () async { when(RepositoryImpl.fetchArticleList(category: Pickup().package, page: 1, size: 20)) .thenAnswer((_) async => Result.success(List.generate(20, (_) => Article()))); await controller.initArticleList(); expect(controller.state.maybeMap( success: (s) => s.articles.length, orElse: () {}, ), 20); expect(pickupArticleListController.page, 1); });
つづいて以上のようにrepositoryのメソッドに必要な引数を設定し、Futureメソッドですので thenAnswer
を用いて返り値を指定してあげます。今回ですとArticle型のListを要素20で生成しました。
その後メソッドを実行し、stateのarticlesの長さが20に変更されているかを確認します。
僕のプロジェクトですと、stateをsuccess, loading, errorの3つの状態で用意していますので今回はAPIがうまくいっているものを前提としているのでsuccessに通ってくるのでmaybeMapを使用しています。
まとめ
Futureメソッドで返り値がResult