问题
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