今日は、RSpecにおけるモックオブジェクト技法について調べてみました。
モックオブジェクト技法とは
モックオブジェクト技法とは、
- オブジェクト同士のコラボレーションに注目したテスト方法。
- オブジェクトの状態よりも、オブジェクト同士のやりとりに注目する。
- インターフェースのテスト、シーケンス図のテストに注力した技法。
詳しくは、この本がいい。
RSpecにおけるテストダブル
基本は以下。double()メソッドでテストダブルオブジェクトを生成。
テストダブルとは、本物のオブジェクトの代役をするオブジェクト。 映画の俳優のスタントマン。
大抵の場合は、テスト対象のオブジェクトの引数としてオブジェクトが渡される。
real_foo = Foo.new
double_foo = double('foo')
# real_fooをつかわないで、double_fooを渡す
hoge = Hoge.new(double_foo)
記法には2種類ある。
- should記法 should_recieve …
- expect記法 allow/expect
expect記法の方が、より英語らしく感じる。文脈に応じて使い分ける。
スタブ
スタブメソッドを指定すると、 テストダブルオブジェクトのメソッドから好きな値を戻り値として得ることができる。
allow(double_foo).to receive(:call).and_return("Hello")
double_foo.stub(:call).and_return("Hello")
モック
スタブに検証機能をつけたものをモックという。検証機能とは、
- 期待された引数で呼ばれたか?
- 期待された回数呼ばれたか?
- 期待された順番で呼ばれたか?
などなどを検証する。この機能が、モックオブジェクト技法。 オブジェクト同士のやりとりに注力したテストがかける。
期待された値で呼ばれたかは、with()メソッドで検証する。
expect(double_foo).to recieve(:call).and_return("Hello")
double_foo.should_recieve(:call).and_return("Hello")
リファレンスとか
実装例
その他所感
Mock系のツールは、GoogleMockとJMockをつかったことがあるけれども、 RSpecの記法はとてもシンプルなので、気に入った。
JavaやC++だと、いちいちインタフェースを定義しないといけない。
Rubyでは、それがないの