在我的 Rails 应用程序中,我有一个 User
模型:
class User
def self.foo
User.all.each{ |user| user.bar }
end
def bar
end
end
在我的规范文件中,我想检查 foo
是否为每个用户调用 bar
,到目前为止,这就是我所拥有的:
describe '::foo' do
let!(:users) { Fabricate.times(5, :user) }
it 'calls bar for every user' do
users.each do |user|
expect(user).to receive(:bar)
end
User.foo
end
end
虽然该方法被调用(我调试了它,所以我确信这一点),但规范是红色的。
我还尝试编写此代码来了解问题出在哪里:
let!(:user) { Fabricate(:user) }
it 'fails' do
expect(user).to receive(:bar)
User.first.bar
end
it 'pass' do
expect(user).to receive(:bar)
user.bar
end
看来,如果我直接引用我的实例,它就可以工作,如果我从数据库获取它,则期望不起作用。
我使用 mongoid,不确定这是否相关。
最佳答案
我认为由于 RSpec 的工作方式而无法完成:当您设置期望时,RSpec 本质上会“包装”对象,以便它可以跟踪它收到的消息。
但是当实现代码从数据库获取记录时,它们没有被包装,因此 RSpec 无法记录它们的消息。
RSpec 确实有一个方法 allow_any_instance_of
在某些情况下可以提供帮助,但不鼓励使用它,并且认为它不适合这里。
在这种情况下,我建议对 User.all
进行 stub 处理以返回一些 double (两个就足够了)。然后,您可以验证是否在每一个上调用了 bar
。
关于ruby-on-rails - RSpec:如果未直接引用对象,则expect.to 接收失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30623836/