モック、スパイ、ダミー、スタブ、フェイクの意味の違い

オブジェクト設計スタイルガイド』7章の章末問題の解説で、今までわかりづらかった以下のテスト用語について簡潔な説明がありました。

  • モック
  • スパイ
  • ダミー
  • スタブ
  • フェイク

意味は以下のとおりです。

モックそのメソッドの呼出が行われたことを保証する
スパイそのメソッドの呼び出しが行われたかどうかを後で確認する
ダミー正しい型だけを持つ非機能的なオブジェクト
スタブ正しい型を持ち、事前に設定した値を返すオブジェクト
フェイクより進化したオブジェクト、それ自体のロジックも持つ

クエリメソッドとコマンドメソッド

コマンドクエリ分離の法則(command/query separation principle, CQS) というルールがある。

クエリメソッドは特定の戻り値を持ち、副作用がない。クエリは情報の断片を取得するために使用できるメソッドである。何度呼び出してもアプリケーションの状態は変わらない。

コマンドメソッドは副作用を持つことができる。コマンドメソッドの戻り地は void とする。

クエリは副作用を持たないため、クエリメソッドからはコマンドメソッドは呼び出さない。

クエリメソッドに対してどの種類のテストダブルを使うか?

以下のようなクエリメソッドに対して、どの種類のテストダブルを使うか?

interface UserRepository {
  public function getById(userId: UserId): User
}

クエリメソッドに対しては

  • ダミー
  • スタブ
  • フェイク

を使う。クエリメソッドはモック化すべきではない。

コマンドメソッドに対してどの種類のテストダブルを使うか?

interface UserRepository {
  public function save(user: User): void
}
  • モック
  • スパイ

を使って、メソッドが呼び出されたことを確認する。