我有一个方法
foo(bars)
bars
是ActiveRecord::Relation
在我的规范中,我想断言使用foo
调用bars
,但在规范bars
中只是一个数组
let(:bar) { create(:bar) }
let(:bars) { [bar] }
expect(described_class).to receive(:foo).with(bars)
有没有办法实现这个目标?在我根据传递的bars
测试bars
的过滤时,我无法在控制器中存根params
。
答案 0 :(得分:2)
您可以设置对某些内容的期望,并让它运行原始代码。只需添加and_call_original
即可:
expect(described_class).to receive(:foo).with(bars).and_call_original
答案 1 :(得分:0)
您可以检查条形是您期望的值,而不是伪造条形码:
expect(described_class).to receive(:foo) do |bars|
# verify bars here. You could do bars.to_a and check the array
# or bars.to_sql and check the generated sql.
end
答案 2 :(得分:0)
我尝试了类似let(:bars) { BarClass.where(id: [bar.id]) }
的操作,因此预期的bars
也是ActiveRecord::Relation
。但是由于ActiveRecord::Relation#==
方法,它没有用。我的expected
具有与actual
不同的SQL。
From: gems/activerecord-6.0.2.1/lib/active_record/relation.rb @ line 682:
Owner: ActiveRecord::Relation
Visibility: public
Number of lines: 10
def ==(other)
case other
when Associations::CollectionProxy, AssociationRelation
self == other.records
when Relation
other.to_sql == to_sql
when Array
records == other
end
end
但是在搜索RSPEC代码时,我发现.with()
接受块。不是直接在receive
上。正如@Jeff F.所写。
并且因为我需要在export
方法上存根返回值,所以结果都以:
exporter_double = instance_double(Xml::Exporter::InventoriesExporter, export: "<xml>Result of export to POHODA for [#{inventories.collect(&:code).join(',')}]</xml>")
expect(Xml::Exporter::InventoriesExporter).to receive(:new) do |arg1, arg2, arg3|
# doing my own `.with(inventories, :xml, {})` because actual `inventories` is ActiveRecord::Relation, not array
expect(arg1.to_a).to eq(inventories)
expect(arg2).to be(:xml)
expect(arg3).to eq({})
end.and_return(exporter_double)