如何在rspec中的模型副本上存根方法?

Mik*_*iet 0 testing activerecord rspec ruby-on-rails

说我有下一个代码:

class Foo < ActiveRecord::Base

  def self.bar
    all.each(&:bar)
  end

  def bar
    # do something that I want stub in test
  end
end
Run Code Online (Sandbox Code Playgroud)

现在我要创建测试(Rspec):

foo = Foo.create
expect(foo).to receive(:bar)
Foo.bar
Run Code Online (Sandbox Code Playgroud)

此测试未通过,因为Foo.bar调用同一模型的其他实例foo.

我之前在这种情况下编写了一些复杂的代码,例如:

expect_any_instance_of(Foo).to receive(:bar)
Run Code Online (Sandbox Code Playgroud)

但这并不好,因为没有信心foo接收消息(可能有几个实例).并且expect_any_instance_ofRspec维护者也不推荐.

你如何测试这样的代码,是最好的做法吗?

MrD*_*anA 5

如果要对每个实例进行细粒度控制,可以执行以下操作:

foo_1 = Foo.create
expect(foo_1).to receive(:bar).and_return(1)
foo_2 = Foo.create
expect(foo_2).to receive(:bar).and_return(2)

# This makes it so our specific instances of foo_1 and foo_2 are returned.
allow(Foo).to receive(:all).and_return([foo_1, foo_2])

expect(Foo.bar).to eq [1, 2]
Run Code Online (Sandbox Code Playgroud)