0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】テストだけじゃない!libでもmockitoを活用する方法

Posted at

本記事は以下で投稿した内容と同じです。

はじめに

テストではmockitoを使ってクラスのモックとスタブを作成することがよくあると思います。

しかし、実はこのmockitoはテストファイル以外にも使えることを最近知ったのでご紹介したいと思います。

記事の対象者

  • lib配下でもmockitoを使ってみたい方
  • ひとまず画面でモックデータを使ってUIを構築したい方

記事を執筆時点での筆者の環境

[✓] Flutter (Channel stable, 3.27.1, on macOS 15.1 24B2082 darwin-arm64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.2)
[✓] VS Code (version 1.96.2)

モック関連の準備

Userのモデル

class User {
  User({
    required this.name,
    required this.email,
    required this.password,
  });

  final String name;
  final String email;
  final String password;
}

モック対象のクラス または パッケージ

今回はSharedPreferencesを例にしますのでインストールしておきます。

mockitoのインストール

こちらもお忘れなく

モックの作成

lib内でモックを作成する

テストの時と同様にモックを使用したいファイル内にモックを作成していきます。
今回はUserモデルとSharedPreferencesをモックします。

import 'package:flutter/material.dart';
import 'package:mockito/annotations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simple_base/domains/user.dart';

@GenerateNiceMocks([
  MockSpec<SharedPreferences>(),
  MockSpec<User>(),
])
class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  ...
}

build.yamlを設定して自動生成する

このままbuild_runnerを走らせてもモックを生成してくれません。
なのでルートディレクトリ直下にbuild.yamlを作成して以下のように記入してください。

targets:
  $default:
    builders:
      mockito|mockBuilder:
        generate_for:
          - test/**.dart
          - lib/**.dart

これによって、testディレクトリ配下だけではなく、libディレクトリ配下でも自動生成が有効になります。
自動生成を走らせてみてください。

モックにスタブを設定する

testでスタブを作る時と同じくwhenでスタブを作ると反映されます。

import 'package:flutter/material.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simple_base/domains/user.dart';
import 'package:simple_base/main.mocks.dart';

@GenerateNiceMocks([
  MockSpec<SharedPreferences>(),
  MockSpec<User>(),
])
class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final user = MockUser();
    when(user.name).thenReturn('John Doe');
    when(user.email).thenReturn('john@example.jp');
    when(user.password).thenReturn('password');

    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Column(
            spacing: 20,
            children: [
              Text(
                'Name: ${user.name} \nEmail: ${user.email} '
                '\nPassword: ${user.password}',
              ),
              ElevatedButton(
                onPressed: () {
                  final prefs = MockSharedPreferences();
                  when(prefs.getString('key')).thenReturn('モックの値を取得しました');
                  final value = prefs.getString('key');
                  if (value == null) return;

                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text(value)),
                  );
                },
                child: const Text('モックのメソッドをタップ'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

mockito_in_lib.gif

注意点

ただのサンプルプロジェクトならこれでいいのですが、リリース前提のプロジェクトではもう少し慎重に扱った方が良いでしょう。

まずはbuild.yamlに自動生成を許容するファイルを限定しておく必要があると思います。
誤って本番用のファイルに混入してしまうのを防ぐためです。
例えば以下のように具体的なファイルを指定する方法です。

targets:
  $default:
    builders:
      mockito|mockBuilder:
        generate_for:
          - test/**.dart
          - lib/debug/debug_screen.dart # <= 💡 ファイルまで指定する

その上で上記の例のようにdebug_screenだけに限定したとします。
このdebug_screenFlavorを使って開発環境のみ表示するように限定するなどにした方が良いでしょう。

開発環境の分け方は以下で解説しています。

終わりに

通常、mockito はテスト環境で使われることが多いですが、
デバッグや開発時のモックデータの取り扱いが簡単になります。
この方法をうまく活用することで、より柔軟にモックデータを扱いながら開発を進めることができます。
ぜひ試してみてください!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?