如何在RSpec中存根两个链式ActiveRecord方法?

时间:2016-08-29 22:12:24

标签: ruby-on-rails ruby rspec

我有一段这样的代码:

Green::Trees.where(id: ids).find_each do |tree|
  tree.grow!
end

什么是存根find_each的好方法,以便在每次迭代中,它返回一个我在测试中的let块中定义的树,如下所示:

let(:tree) { create(:tree) }
let(:tree_ids) { [tree.id] }

我该怎么办?

我应该这样做吗?

allow(Green::Tree).to receive(:where).and_return(Green::Tree)
allow(Green::Tree).to receive(:find_each).and_yield(tree)

1 个答案:

答案 0 :(得分:3)

RSpec为您提供了两种存根链接方法调用的方法。

简洁的方法是receive_message_chain

allow(Green::Trees).to receive_message_chain(:where, :find_each).and_yield(tree)

但是,这并不能指定参数,尽管这样做通常并不重要。

如果您关心参数,可以这样做:

results = double
allow(Green::Tree).to receive(:where).with(id: ids).and_return(results)
allow(results).to receive(:find_each).and_yield(tree)

您所写的内容可行,但由于where没有返回类Green::Tree,而是ActiveRecord关系,因此不正确。 Green::Tree确实实现了find_each,但它是一个与关系上的名称相同的不同方法。非常混乱!