I have an Order model, which has_many payments and a checkout Controller. The Controller should create a new payment if no payment exits.
private
# Helper method allows calling from several controller-callbacks.
def add_payment_if_not_exists
if @order.payments.empty?
Payment.create(...)
end
end
And now I want to spec this behaviour in CheckoutControllerSpec
it 'should not add a payment when already added' do
@order = mock_model(Order)
@order.payments << mock_model(Payment).as_null_object
Payment.should_not_receive(:new)
post :homecoming, @params
end
But this throws
Failure/Error: @order.payments << mock_model(Payment).as_null_object
Mock "Order_1003" received unexpected message :payments with (no args)
Somehow I still do not grok rspecs stubbing and mocking concept entirely. What am I aoing wrong?
Here you create a mock object, just a blank canvas. If you want to set stuff, you should tell it to respond to :payments with something. In this case, an array with 1 entry (a mock Payment object)
That will get you further down the road. Other notes:
Payment.should_not_receive(:new)tests your behavior. You actually call Payment.create, not Payment.newHere we say that #payments returns a non-empty array, and we don’t care about the contents.