自動テストのスタブ・スパイ・モックの違い
ソフトウェアの自動テストで使う代品オブジェクト――いわゆる「 テストダブル 」の種類についてまとめました。 タイトルには「スタブ」「スパイ」「モック」の 3 つだけをあげていますが、他にも「フェイクオブジェクト」と「ダミーオブジェクト」に言及しています。
お断り
- この記事の説明は書籍『 xUnit Test Patterns: Refactoring Test Code 』( Gerard Meszaros 著)の定義に基づいています。
- このあたりの用語の定義は人や流派によって異なります。この記事の説明が常に正しいわけではありません。
テストダブルの全体像
テストダブルの分類は次のようになっています。
テストダブル├ テストスタブ├ テストスパイ├ モックオブジェクト├ フェイクオブジェクト└ (ダミーオブジェクト)
テストスタブ・テストスパイ・モックオブジェクト等のテスト用の道具をまとめてテストダブルと呼びます。 テストダブルとはプログラムの中でオブジェクトや関数やモジュール(以下これらをまとめて「コンポーネント」と呼びます)の代品として動く仮のコンポーネントのことです。
ちなみに、ダブル( double )という単語は多義的で、日本人におなじみの「倍」の他にもたくさんの意味を持っています。 その中には、スタントマン的な「代役」「影武者」、他人にうりふたつの「生き写し」という意味もあり、「テストダブル」の「ダブル」の意味合いはおそらくこのあたりにあるのだと思います。
各テストダブルの意味
テストダブルの下の各分類について順に説明していきます。
- テストスタブ
- テストスパイ
- モックオブジェクト
- フェイクオブジェクト
- (ダミーオブジェクト)
テストスタブ
テストスタブ (あるいは単に スタブ )とは、テスト対象物(= Systems under Test 、以下「 SUT 」)が利用するコンポー ネント(= Dependant on Components 、以下「依存コンポーネント」)の代品として動作するものです。 テスト技術者があらかじめ指定したとおりの挙動をします。
テストスタブを利用することで、特定の状況下での SUT の挙動のテストがやりやすくなります。 挙動というのは OOP のパラダイムでは「メソッドの戻り値」や「 public なプロパティの値」のことです。
テストスタブは「 SUT の依存コンポーネントが仮にこんな挙動をしたら SUT はこういう挙動をするはず」というテストにおける「仮にこんな挙動をしたら」の部分を実現するためのものです。 『 xUnit Test Patterns 』の表現を使うなら、テストスタブは SUT に 間接インプット (= indirect inputs )を与えるためのものです。
テストスタブ →(間接インプット)→ SUT
ポイント:
- 特定の状況下での SUT の挙動を確認するために SUT の依存コンポーネントの代品として動作する
- あらかじめ指定されたとおりの挙動をする
テストスパイ
テストスパイ (あるいは単に スパイ )とは、 SUT の依存コンポーネントにどのようなアクセスがあったかを記録するものです。
コンポーネントへのアクセスというのは OOP では「メソッド呼び出し」のことです。 単に呼び出しを記録するだけではなく、記録した内容について検証を行う機能を兼ね備えていることもあります。
テストスパイは、テスト対象の一連の処理をひととおり実行した後に「メソッドは呼び出されたかどうか」「メソッドは何回呼び出されたか」「メソッドに渡された実引数は何だったか」といったポイントを検証したいときに使用します。 『 xUnit Test Patterns 』の表現を使うなら、テストスパイは SUT から外部への 間接アウトプット(= indirect outputs )を確認するためのものです。
SUT →(間接アウトプット)→ テストスパイ
具体的なパターンとしては、本物のコンポーネントを包み込むラッパーとして実装されているものと、本物のコンポーネントをまるごと入れ替えるテストスタブに記録機能が加わったものとがあります(他にもあるようですが、代表的なものはこの 2 つかと思います)。
ポイント:
- SUT から他コンポーネントへのアクセスを記録する
モックオブジェクト
モックオブジェクト (あるいは単に モック )とは、 SUT の依存コンポーネントの代品として動作し、リアルタイムにコンポーネントへのアクセスを検証するものです。
基本的な機能はテストスパイと同じですが、テストスパイが対象の処理が終わった後に検証を行うのに対し、モックオブジェクトは対象の処理の途中にリアルタイムに検証を行います。 また、モックオブジェクトもテストスパイと同じくスタブの機能を併せ持っていることがあります。
SUT →(間接アウトプット)→ モックオブジェクト
ポイント:
- SUT から他コンポーネントへのアクセスをリアルタイムに検証する