Rspec期望接收ActiveRecord :: Relation的方法

时间:2016-02-12 16:34:34

标签: ruby-on-rails ruby activerecord rspec

我有一个方法

foo(bars)

barsActiveRecord::Relation

在我的规范中,我想断言使用foo调用bars,但在规范bars中只是一个数组

let(:bar) { create(:bar) }
let(:bars) { [bar] }

expect(described_class).to receive(:foo).with(bars)

有没有办法实现这个目标?在我根据传递的bars测试bars的过滤时,我无法在控制器中存根params

3 个答案:

答案 0 :(得分:2)

您可以设置对某些内容的期望,并让它运行原始代码。只需添加and_call_original即可:

expect(described_class).to receive(:foo).with(bars).and_call_original

此处提供的文档详情:http://www.relishapp.com/rspec/rspec-mocks/v/3-4/docs/configuring-responses/calling-the-original-implementation

答案 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)
相关问题