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

时间:2016-01-27 14:34:05

标签: ruby-on-rails testing activerecord rspec

说我有下一个代码:

foo = Foo.create
expect(foo).to receive(:bar)
Foo.bar

现在我想创建test(Rspec):

Foo.bar

此测试未通过,因为foo调用同一模型expect_any_instance_of(Foo).to receive(:bar) 的其他实例。

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

foo

但这并不好,因为expect_any_instance_of没有信心收到消息(可能有几个实例)。并且Rspec维护者不推荐使用You would need to modify the web.config as follows: <configuration> <system.web> <httpRuntime maxRequestLength="1048576" /> </system.web> </configuration>

如何测试此类代码,是最佳做法吗?

2 个答案:

答案 0 :(得分: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]

答案 1 :(得分:-1)

在你的例子中:

class Foo < ActiveRecord::Base

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

  def bar
    # do something that I want stub in test
  end
end

如果foo = Foo.new

请注意,foo.barFoo.bar不同。

前者调用实例方法def bar(你想要存根),而后者调用类方法def self.bar

然而,在你的测试中,

foo = Foo.create
expect(foo).to receive(:bar)
Foo.bar

您正在尝试存根实例方法def bar(expect(foo)。接收(:bar)),同时调用类方法def self.bar(Foo.bar)

这就是为什么它似乎不起作用。