モック(mock)とスタブ(stub)の違いが分からないままなんとなく使っていたので、調べてみた。
先にざっくり結論
対象の処理をテストしたい場合はモック。テストしたいのは別の部分で、とりあえず値を返してくれればOKであればスタブを利用する。
そもそもなぜ使うのか
Rspecなどを用いてテストを書く場合、APIなどを用いたHTTP通信をそのまま利用してしまうと、APIのタイムアウトなどが原因でテストが失敗になってしまう恐れがある。これを防ぐために、APIなどの代わりに決まった結果を返すのがスタブやモックの役割。
共通している部分
代わりに処理を返すことに関しては同じ。
- messageを受け取ったら、valueを返す処理
# create a double
obj = double()
# specify a return value
obj.should_receive(:message).and_return(:value)
モックとスタブの違い
違いは対象の処理をテストできるかどうか。
モックの場合は対象の処理に対して、様々な条件でテストを実装することができます。
引数の中身でテスト
# 引数に'an argument'が存在する
obj.should_receive(:message).with('an argument')
呼び出し回数でテスト
# messageを少なくとも一回は呼び出している
obj.should_receive(:message).at_least(:once)
このように、モックにした部分をテストすることができる。
結論
テストを行いながら決まった値を返して欲しい時はモック。単純に決まった値を返して欲しい場合はスタブ。このような理解で良いのかなと思います。
参考
モックのドキュメント
https://relishapp.com/rspec/rspec-mocks/v/2-14/docs/message-expectations
スタブのドキュメント
https://relishapp.com/rspec/rspec-mocks/v/2-14/docs/method-stubs
[図解]スタブとモックの違い
Railsでrspecを使うように設定する