0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RSpec で メソッドをモックしたいときに mock 用の allow メソッドと singleton メソッドを使うか迷ったときは allow メソッドを使うべき

Posted at

概要

rspecではテストをしやすくするために、メソッドをモックしたいときがよくあると思います。

下記の例では set_complex_config メソッドにadmin?メソッドが影響を受けるのですが、

set_complex_config メソッドはすでにそれ自体のテストコードがあり、そのレスポンスのみ欲しいという状況です。

# コード例は適当です
class User
  def admin?
    res = set_complex_config
    case res
    when 'hoge'
      'hoge'
    when 'fuga'
      'fuga'
    end
  end

  def set_complex_config
    # 複雑な処理
  end
end

このような場合のモックの仕方として私は2通りのやり方が思いつくので、どちらが良いかを考えてみました。

mockの仕方

① singleton メソッドを定義してmockする

下記のように User クラスの set_complex_config メソッドを singleton メソッドで上書きする方法です。

let(:hoge_let) { 'hoge' }
it do
  user = create(:user)
  hoge_var = 'hoge'
  user.define_singleton_method(:set_complex_config) { hoge_var }
  user.set_complex_config => 動く

  user.define_singleton_method(:set_complex_config) { hoge_let }
  user.set_complex_config => wrong number of arguments (given 0, expected 2..3)
end

一見かっこいいですが、この場合、example内やbeforeブロック内で、define_singleton_method メソッドのブロックはlet変数を読むことができません。

② allow メソッドでmockする

allow メソッドでは問題なく動きます。

let(:hoge_let) { 'hoge' }
it do
  user = create(:user)
  allow(user).to receive(:attributes).and_return(hoge_let)
  user.set_complex_config => 動く
end

結論

素直にallow().to receive().and_return()を使った方が良さそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?