テストダブルとは?
テストダブルとは、テストにおいて実際の依存を代替する任意のオブジェクトであり、mock、stub、spy、fake、dummy を含みます。
テストダブルは、スタントダブル(代役)の考え方から借用された総称で、テスト中に実際の協調オブジェクトを置き換えるものすべてを指します。mock、stub、spy、fake、dummy はすべてテストダブルです。この一族を知ることで、仕事をこなす最も軽量なツールを選べるようになります。
そもそもなぜダブルを使うのか
実際の依存は、遅かったり、非決定論的だったり、コストが高かったり、あるいはテスト環境で単に利用できなかったりします。ダブルはそれらを高速で制御可能なものに置き換え、テストが外の世界の振る舞いではなくテスト対象のコードに集中できるようにします。
5 つの種類
- Dummy: 受け渡されるが、実際には使われることがない。
- Stub: あらかじめ用意された答えを返す。
- Spy: どのように呼び出されたかを記録し、多くの場合は実際の振る舞いをラップする。
- Mock: 検証する期待値があらかじめプログラムされている。
- Fake: インメモリストアのような、実際に動作するが簡略化された実装。
簡単な例
インメモリのリポジトリは fake です。実際のデータベースなしでテスト内で動かせるほど単純な、動作する実装です。
A fake standing in for a database
class FakeUserRepo {
constructor() { this.users = new Map(); }
save(u) { this.users.set(u.id, u); }
find(id) { return this.users.get(id); }
}適切なダブルを選ぶ
うまくいく中で最も単純なダブルを使いましょう。値さえあればよいときは dummy か stub で十分です。相互作用を検証する必要があるときは spy か mock を、実際の依存なしに現実的な振る舞いが必要なときは fake を使います。stub で済むところに重量級の mock を持ち出すと、テストが壊れやすくなります。
テストダブルと CI の速度
ダブルは I/O や外部サービスを取り除きます。だからこそ、それらを使うユニットテストは高速に実行され、CI でめったに不安定にならないのです。残る不安定さは、実際の依存を使うテストに存在します。そこでは Latchkey が本当に一時的な失敗を自動的にリトライするため、不安定な外部呼び出しが良好な build を誤って不合格にすることがありません。
重要なポイント
- テストダブルは、mock、stub、spy、fake、dummy を包括する総称です。
- それぞれの種類は、現実性と制御性のトレードオフの取り方が異なります。
- 自分が重視する振る舞いを検証できる、最も軽量なダブルを選びましょう。
関連ガイド
What Is a Mock?Mocks explained: how a mock stands in for a real dependency and verifies interactions, how it differs from st…
What Is a Stub?Stubs explained: how a stub returns canned responses to keep a test deterministic, how it differs from a mock…
What Is a Spy?Spies explained: how a spy records calls to a real or wrapped function so you can assert on them, how it comp…
What Is a Test Fixture?Test fixtures explained: the known, repeatable state a test runs against, setup and teardown, an example, and…