Ruby on rails RSpec存根服务对象方法

Ruby on rails RSpec存根服务对象方法,ruby-on-rails,rspec,Ruby On Rails,Rspec,我在从AR对象删除对服务对象(QuickbooksService)的调用时遇到问题。据我所知,该方法应该正确地存根并返回我指定的值,但当我运行规范时,我可以看到该方法被调用并失败 这是我正在测试的对象的类定义 class Order < ActiveRecord::Base def create_invoice QuickbooksService.new(:estimate).create_invoice(arg1, arg2, arg3) end end 我也试过了 a

我在从AR对象删除对服务对象(QuickbooksService)的调用时遇到问题。据我所知,该方法应该正确地存根并返回我指定的值,但当我运行规范时,我可以看到该方法被调用并失败

这是我正在测试的对象的类定义

class Order < ActiveRecord::Base
  def create_invoice
    QuickbooksService.new(:estimate).create_invoice(arg1, arg2, arg3)
  end
end
我也试过了

allow(QuickbooksService.new(:estimate)).to receive(:form_invoice_create).with(anything()).and_return(1)

因此,QuickbooksService内部正在执行
create\u invoice
方法,而不是返回
1
。如有任何见解,将不胜感激

问题在于,您正在实例化该类,同时将其存根为
allow(QuickbooksService.new(:estimate))。以接收(:form\u invoice\u create)。使用(anything())和返回(1)

试试这个:

allow_any_instance_of(QuickbooksService).to receive(:form_invoice_create).with(anything()).and_return(1)

您遇到的问题是,您正在存根一个单独的实例。i、 e当您定义期望时,您告诉它期望某个特定实例接收到对该方法的调用,但当代码被执行时,它正在创建一个不同的实例。您需要做的是允许任何实例接收方法调用。类似于
允许(QuickbooksService)的任何实例。接收(:invoice\u create)
会起作用,但创建一个double更好,类似于:

let(:quickbooks_service) { instance_double(QuickbooksService) }

describe("#create_invoice") do
  before { allow(quickbooks_service).to receive(:create_invoice).and_return(1) }

  it "Creates quickbook invoice" do
    order.create_invoice
    expect(quickbooks_service).to have_received(:create_invoice)
  end
end

请参阅:

非常感谢!我正在查看
实例\u double
文档,但没有像您那样将其放在一起。干杯我会投赞成票,但我缺少代表。。8(是否可以使用参数声明实例?QuickbooksService对象的此特定实现需要参数
:estimate
,如果没有参数,存根将无法工作。我在文档中看不到任何引用此可能性的地方。当然!您可以使用
。与(…)匹配参数
e.g
before{allow(quickbooks\u service).to receive(:create\u invoice).with(arg1,arg2,arg3).and\u return(1)}
对不起,我指的是实例\u double的声明。我想像
实例\u double(QuickbooksService.new(:estimate))一样实例化它
但是RSpec不喜欢这样。确切地说,这是不正确的实现。
实例_double
将类名或对象作为其第一个参数,然后验证被存根的任何方法是否存在于该类的实例上。
let(:quickbooks_service) { instance_double(QuickbooksService) }

describe("#create_invoice") do
  before { allow(quickbooks_service).to receive(:create_invoice).and_return(1) }

  it "Creates quickbook invoice" do
    order.create_invoice
    expect(quickbooks_service).to have_received(:create_invoice)
  end
end