テストダブルとは何か

はじめに

単体テストを書く際、テスト対象のコードが外部のデータベース、APIサーバー、ファイルシステムなどに依存していると、以下のような問題が発生する:

  • テストの実行が遅い
  • テスト環境の準備が複雑
  • テスト結果が不安定(ネットワークエラーなど)
  • 特定の状態やエラーケースの再現が困難

これらの問題を解決するために使われるのが**テストダブル(Test Double)**である。

テストダブルとは、テストにおいて依存先のコンポーネントを本物の代わりに置き換える「代役」のことである。映画のスタントダブルのように、本物の代わりにテスト専用の実装を使用する。

本記事では、テストダブルの5つの種類(Dummy、Stub、Fake、Spy、Mock)について、それぞれの目的と使い分けを、Goのコード例を交えて解説する。

テストダブルの基礎知識

テストダブルの5つの種類

テストダブルには5つの種類がある。それぞれ目的と使い方が異なる。

種類 目的 特徴
Dummy 引数を埋めるだけ 実際には使用されない
Stub 決まった値を返す 状態検証に使用
Fake 簡易的な実装 実際に動作する軽量版
Spy 呼び出しを記録 履歴を後で検証
Mock 期待を事前設定 振る舞い検証に使用

前提:テスト対象のコード

以下の例では、データストアに依存するサービスをテストする。

テストダブルの種類と実装例

それぞれのテストダブルについて、具体的なコード例と使いどころを見ていく。

1. Dummy

Dummyは、引数を埋めるためだけに存在し、実際には使用されないオブジェクトである。

使用例

使いどころ

  • 関数のシグネチャを満たすために引数が必要だが、実際には使われない場合
  • 呼ばれたら即座に失敗させることで、誤用を検出できる

2. Stub

Stubは、呼び出しに対して決まった値を返すだけの単純な実装である。状態検証に使われる。

使用例

使いどころ

  • テストで特定の返り値やエラーを返したい場合
  • 状態(結果)を検証するテスト
  • 最もシンプルで使いやすいテストダブル

3. Fake

Fakeは、実際に簡易的な動作をする軽量実装である。本物に近い振る舞いをするが、テスト用に簡略化されている。

使用例

使いどころ

  • 複数のテストケースで共通のデータストアが必要な場合
  • 実際の動作に近いテストが必要な場合
  • 統合テストとユニットテストの中間レベルのテスト
  • 例:メモリ内データベース、インメモリファイルシステム

4. Spy

Spyは、呼び出し履歴(引数、回数など)を記録し、後で検証することを目的とする。Mockとの違いは、Spyは事前に期待値を設定せず、実行後に履歴を確認する点である。

使用例

使いどころ

  • メソッドが正しい引数で呼ばれたか確認したい場合
  • 呼び出し回数や順序を検証したい場合
  • ログ記録、通知送信などの副作用を持つ処理のテスト

5. Mock

Mockは、事前に期待(expectation)を設定し、テスト終了後にその期待が満たされたかを検証する。振る舞い検証に特化している。Spyとの違いは、Mockはテスト実行前に「こう呼ばれるべき」という期待を明示する点である。

使用例

使いどころ

  • メソッドが期待通りの順序・引数で呼ばれたか厳密に検証したい場合
  • 複雑な振る舞いの検証が必要な場合
  • 外部サービスとのインタラクションをテストする場合

まとめ

テストダブルは、単体テストを高速で安定させ、テストしづらいコードをテスト可能にする強力なツールである。

  1. まず依存関係をインターフェースとして抽象化する
  2. 状態検証にはStub/Fakeを使う
  3. 振る舞い検証にはSpy/Mockを使う
  4. Mockは必要最小限に抑える
  5. テストダブルはシンプルに保つ

適切なテストダブルを選択することで、保守性が高く、リファクタリング耐性のあるテストを書くことができる。

参考