I need to write an expectation that a new object will be created in a payment system. Code included from order.rb
and order_spec.rb
(Order
class is here):
#order.rb
def confirm_order(method_of_payment)
if credit_card_but_products_out_stock?(method_of_payment)
raise "Cannot make credit card payment now, as some products are out of stock"
end
order_total
Payment.new(method_of_payment, self.total)
end
#order_spec.rb
it 'it creates a new payment object if method_of_payment is valid and order.total is > 0' do
order.add_product(product, 3)
order.confirm_order(:credit_card)
#Expect that a new payment object is created.
end
I want to understand how I can write the appropriate spec to test that the new Payment object is created. I found this article from Semaphore CI useful, but am not sure about a solution. I am pretty sure I should be creating a test double of some sort, and then maybe a method stub to allow(order).to receive(:confirm_order).and_return(#new_object??)
.
If you're unit testing the Order
class, then you shouldn't be mocking or stubbing the Order
class. You could set an expectation on the Payment
class to return a mock that you can then further assert as the return value of confirm_order
method.
let(:payment) { double :payment }
it "returns a payment" do
expect(Payment).to receive(:new).with(:credit_card).and_return(payment)
order.add_product(product, 3)
expect(order.confirm_order(:credit_card)).to eq(payment)
end
This way, you are mocking the dependencies of your Order
class, without altering the Order
class, which is much safer as mocking method on Order
could easily create false-positive test results.