如何在RSpec中编写Klass.any_instance_with_id(id).expects(:method)

时间:2014-01-25 11:32:53

标签: ruby-on-rails rspec

使用RSpec编写测试时,我经常需要表达类似

的内容
Klass.any_instance_with_id(id).expects(:method)

主要原因是在我的测试中,我经常有一个应该接收该方法调用的对象,但是由于ActiveRecord在从数据库加载带有该id的对象时会创建一个不同的实例,不能把“期望”放在我自己的实例上

有时我可以通过查找方法来强制ActiveRecord加载我的实例,有时我可以存根其他方法,但是拥有“any_instance_with_id”会让生活变得更加轻松......

无法成像我是第一个遇到这个问题的人......所以,如果你们中的任何人找到了“解决方法”,我很乐意找到答案!

说明需要的示例:

控制器规范:

describe 'an authorized email' do
  let(:lead) { create(:lead, status: 'approved') }

  it "should invoice its organisation in case the organisation exceeds its credit limit" do
    lead.organisation.expects :invoice_leads
    get :email
  end
end

控制器:

def email
  leads = Lead.approved

  leads.each do |lead|
    lead.organisation.invoice_leads if lead.organisation.credit_limit_exceeded?
  end

  redirect_to root_path
end

1 个答案:

答案 0 :(得分:0)

对我而言,你需要那些规格似乎很奇怪。

您应该将问题提高一级:当您的应用尝试检索记录时。

示例:

#code 
@user = User.find(session[:user_id])

# spec
let(:fake_user) { mock_model 'User', method: false }

it 'description' do
  User.should_receive(:find).and_return fake_user
  fake_user.expects(:method)

  #...
end

订单/发票示例:

let(:order)   { mock_model 'order', invoice: invoice }
let(:invoice) { mock_model 'Invoice', 'archive!' => false }