テストダブルについて
テストダブルとは
ソフトウェア開発における テストダブル(Test Double) とは、 テスト対象が依存しているコンポーネント(依存オブジェクト)を テスト用に置き換えた「身代わり」の総称です。 映画のスタントダブル(替え玉)が語源で 本物を使うのが難しいあるいは不都合な場合に利用されます。
なぜテストダブルが必要か?
本物のオブジェクトの代わりにテストダブルを使う主な理由は以下の通りです。
- 実行速度の向上: データベースや外部 API へのアクセスを回避し、テストを高速化する。
- 決定論的なテスト: 時刻や乱数など、結果が変動する要素を固定する。
- 異常系のシミュレーション: サーバーダウンやネットワークエラーなど、意図的に発生させにくい状況を作る。
- 依存の切り離し: 未完成のモジュールや外部サービスに依存せず、特定のロジックのみを検証する。
テストダブルの5つの種類
ジェラルド・メザロス(Gerard Meszaros)氏によって定義された、代表的な 5 つのパターンを紹介します。
- ダミー (Dummy)
- 引数のリストを埋めるためだけに渡されるオブジェクトです。実際にはメソッドが呼ばれることはなく、動作に影響を与えません。
-
スタブ (Stub) テスト時にあらかじめ決められた回答(固定値)を返すオブジェクトです。
例: 「ユーザー情報を取得する関数」が、常に ID: 123 のテストデータを返すようにする。 -
スパイ (Spy) スタブの機能に加え、どのように呼び出されたかを記録するオブジェクトです。
例: 「メール送信関数」が、何回呼び出されたか、どんな引数(アドレスなど)で呼ばれたかを記録し、後で検証する。 -
モック (Mock) 「期待される呼び出し」を事前に定義しておき、その通りに動いたかを検証するオブジェクトです。スパイと似ていますが、モックは「振る舞いの検証」に重点を置きます。
-
フェイク (Fake) 実際に動作する実装を持ちますが、本物より単純化されたオブジェクトです。
例: 本物のデータベース(PostgreSQL など)の代わりに、メモリ内で動作する軽量なデータベース(H2 やインメモリ Map)を使用する。
比較表
| 種類 | 主な目的 | 動作の実装 |
|---|---|---|
| Dummy | コンパイルを通す、引数を満たす | なし |
| Stub | テストに必要な間接的な入力を提供する | 固定値を返す |
| Spy | 呼び出し状況を記録する | 記録 + スタブ機能 |
| Mock | 期待通りの振る舞いをしたか検証する | 事前定義された期待値との比較 |
| Fake | 本物の代わりとして機能させる | 簡易的なロジックあり |
まとめ
テストダブルを適切に使い分けることで、テストの信頼性とメンテナンス性が向上します。 最初はスタブ(状態の検証)とモック(振る舞いの検証)の違いを意識することから始めると理解がスムーズです。