How to stub an object that still has to be loaded from the database in RSpec?

柔情痞子 提交于 2019-12-24 03:50:31

问题


I would like to check whether an object's association receives a certain method call. Problem is that I can stub the object's association, but when later on, the association is loaded from the database, the loaded object is not the same "fysical" object as my stubbed object. It has the same ID, but it is not the same "fysical" object, so the stub doesn't work anymore.

What I currently have is (and this works!)

  it "should register the payment of the invoice if everything ok" do
    invoice = create(:invoice)
    # Dirty trick to get exactly this instance as invoice of the created financial transaction
    FinancialTransaction.any_instance.stubs(:invoice).returns(invoice)
    invoice.expects(:register_payment).with(invoice.derived_total_cost)
    post :create, :financial_transaction => attributes_for(:financial_transaction, invoice: invoice, amount: invoice.derived_total_cost)
  end 

where the second line "guarantees" that I will get the same fysical object. This works, but I consider it a "dirty" solution, as I have to stub FinancialTransaction.any_instance, where in fact I should stub the not-yet-existing financial transaction.

What I would like to have is a way to write something like

  FinancialTransaction.instance_with_id(id).expects(:register_payment)

Question is: how can this be done?


回答1:


I finally solved this as follows

  let!(:invoice) { create(:invoice) }
  let!(:financial_transaction) { create(:financial_transaction, invoice: invoice) }

  before(:each) do
    FinancialTransaction.stubs(:new).returns(financial_transaction)
  end

  it "should register payment of the invoice if everything ok" do
    invoice.expects(:register_payment).with(invoice.derived_total_cost)
    post :create, :financial_transaction => attributes_for(:financial_transaction, invoice: invoice, amount: invoice.derived_total_cost)
  end

This way I can control the associated invoice being used, and as such, can also bind the expectation immediately to this invoice




回答2:


Here's an article outlining some best practices along the same lines as you were thinking.



来源:https://stackoverflow.com/questions/21243833/how-to-stub-an-object-that-still-has-to-be-loaded-from-the-database-in-rspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!