Mocks Aren't Stubs（モックはスタブじゃないよ？）

[Mocks Aren't Stubs](https://martinfowler.com/articles/mocksArentStubs.html) written by [Martin Fowler](https://martinfowler.com/) の mock と stub に関するメモです。[^1]

# 用語について
　[Mocks Aren't Stubs](https://martinfowler.com/articles/mocksArentStubs.html) 内の用語は Gerard Meszaros の [xUnit Test Patterns](http://xunitpatterns.com/) に基づく。

# 結果の検証方法
　[結果の検証](http://xunitpatterns.com/Result%20Verification%20Patterns.html)には、大別して2つの方法がある。

- [State Verification](http://xunitpatterns.com/State%20Verification.html) - 状態を検証する方法
- [Behavior Verification](http://xunitpatterns.com/Behavior%20Verification.html) - 振る舞いを検証する方法

## [Test Double](http://xunitpatterns.com/Test%20Double.html) とは
- テスト内で実際のオブジェクトの代わりに使われるオブジェクトの総称。
- `Double` は Stunt Double（スタントマン）に由来する。
- 既に広く使われている用語を避けるために新しい用語が採用された。

## 5種類の [Test Double](http://xunitpatterns.com/Test%20Double.html)
- [Dummy](http://xunitpatterns.com/Dummy%20Object.html)
    - 渡されるだけで使われることはない。
    - 主に引数リストを埋めるためだけに用いられる。
- [Fake](http://xunitpatterns.com/Fake%20Object.html)
    - 実装を持つが、製品用のものではないものを含む。
    - 例：テスト用にインメモリDBで代替した実装を含むなど。
- [Stub](http://xunitpatterns.com/Test%20Stub.html)
    - テスト中の呼び出しに対する応答が設定されている。
    - テスト内の呼び出し以外は考慮されていないことが多い。
- [Spy](http://xunitpatterns.com/Test%20Spy.html)
    - Stub の一種。
    - 呼び出された情報を記録する。
    - 例：email サービスとしてメッセージの送信数を記録するなど。
- [Mock](http://xunitpatterns.com/Mock%20Object.html)
    - [expectations](http://xunitpatterns.com/expectation.html)（期待された一連の呼び出し仕様）が事前に組み込まれている。

# Mock と Stub の違い
- [behavior verification](http://xunitpatterns.com/Behavior%20Verification.html) を行うのは [mock](http://xunitpatterns.com/Mock%20Object.html) だけ。
- [mock](http://xunitpatterns.com/Mock%20Object.html) 以外は  [state verification](http://xunitpatterns.com/State%20Verification.html) を用いている。
- [mock](http://xunitpatterns.com/Mock%20Object.html) は[実行](http://xunitpatterns.com/exercise%20SUT.html)フェーズでは他の [double](http://xunitpatterns.com/Test%20Double.html) と同様に振る舞うが、[前処理](http://xunitpatterns.com/fixture%20setup.html)と[検証](http://xunitpatterns.com/result%20verification.html)フェーズでは異なる。
- [mock](http://xunitpatterns.com/Mock%20Object.html) による [behavior verification](http://xunitpatterns.com/Behavior%20Verification.html) を [stub](http://xunitpatterns.com/Test%20Stub.html) による [state verification](http://xunitpatterns.com/State%20Verification.html) で代替する場合、[stub](http://xunitpatterns.com/Test%20Stub.html) に検証用のメソッドを追加する必要が生じる場合がある。[^2]

# Classical and Mockist Testing

- classical TDD style
    - 可能な限りは collaborator([DOC](http://xunitpatterns.com/DOC.html)) として実際のオブジェクトを用い、それが難しい場合は [double](http://xunitpatterns.com/Test%20Double.html) を用いる。
- mockist TDD style
    - collaborator([DOC](http://xunitpatterns.com/DOC.html)) として常に [mock](http://xunitpatterns.com/Mock%20Object.html) を用いる。
 
[^1]: 厳密な翻訳とかではないです。
[^2]: 例：メール送信サービスを [double](http://xunitpatterns.com/Test%20Double.html) で置き換える場合に、テスト中に何通のメールを送信したかという情報を [double](http://xunitpatterns.com/Test%20Double.html) から得ようとした場合、[mock](http://xunitpatterns.com/Mock%20Object.html) であれば振る舞いを検証するだけでよいが、[stub](http://xunitpatterns.com/Test%20Stub.html) の場合は [stub](http://xunitpatterns.com/Test%20Stub.html) に送信数という状態を追加して、それを状態として検証しなくてはならない。
[^3]: この章以降では classical TDD style と mockist TDD style の pros and cons を論じているのだが、当時(2007年)と違い現時点(2019年)ではユニットテストと言えばほぼ mockist TDD style であるため(※おいら調べ)。もしそうでなくてもおいら的にはユニットテストの isolation を阻害するようなアプローチに興味はない。