本記事は以下で投稿した内容と同じです。
はじめに
テストでは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('モックのメソッドをタップ'),
),
],
),
),
),
);
}
}
注意点
ただのサンプルプロジェクトならこれでいいのですが、リリース前提のプロジェクトではもう少し慎重に扱った方が良いでしょう。
まずはbuild.yamlに自動生成を許容するファイルを限定しておく必要があると思います。
誤って本番用のファイルに混入してしまうのを防ぐためです。
例えば以下のように具体的なファイルを指定する方法です。
targets:
$default:
builders:
mockito|mockBuilder:
generate_for:
- test/**.dart
- lib/debug/debug_screen.dart # <= 💡 ファイルまで指定する
その上で上記の例のようにdebug_screen
だけに限定したとします。
このdebug_screen
はFlavor
を使って開発環境のみ表示するように限定するなどにした方が良いでしょう。
開発環境の分け方は以下で解説しています。
終わりに
通常、mockito はテスト環境で使われることが多いですが、
デバッグや開発時のモックデータの取り扱いが簡単になります。
この方法をうまく活用することで、より柔軟にモックデータを扱いながら開発を進めることができます。
ぜひ試してみてください!