开发者

Testing setters with RSpec, should_receive, and create?

I'm working on an e-commerce system and familiarizing myself with RSpec.

An order has an associated payment. When the order is completed it starts to process the payment via our payment gateway.

Below is the spec, the a开发者_Go百科ppropriate method, and the failure message.

require 'spec_helper'

describe Order, "#process_payment" do
  let!(:user) { create_user }
  let!(:credit_card) { new_credit_card }
  let!(:order) { user.orders.create! total: 200 }
  let!(:payment) { stub('payment', started_processing!: true, ) }

  before do
    credit_card.stub(sale: true)
    order.stub(credit_card: credit_card)
    order.payments.stub(create!: payment)
    payment.stub(:source= => true, process!: true)
  end

  it "creates a payment" do
    order.payments.should_receive(:create!).
          with(amount: 200, source: credit_card).and_return payment
    order.process_payment
  end

  it "sets the payment's source to the credit card and tells it to process!" do
    payment.should_receive(:source=).with(credit_card).ordered
    payment.should_receive(:process!).ordered
    order.process_payment
  end
end

Here is the Order class.

class Order < ActiveRecord::Base
  ...
  def process_payment
    payments.create!(amount: total, source: credit_card).tap do |payment|
      payment.process!
    end
  end
  ...
end

The second spec is failing, claiming that :source= is never received. With ordered, it just says that process! is called out of order. Without ordered, it says that it expected :source= once, but never received it. I understand why ordered should be there, but just wanted to be clear that it is claiming that :source= is never being received.

Is create! not calling source=? What is the appropriate way to test to make sure the source is being set on the payment correctly?


I would say that your it "creates a payment" spec is enough. The responsibility for the behavior of create! should be in a spec written specifically for it.

If you really want to make sure create! is doing what it's supposed to, perhaps try letting process_payment save to the database then call Payment.last to get the new record and check the properties on it. But I think that would be overkill.

Think of it this way, when you write controller specs you don't test all the behavior of your models again; you just test how your controller interfaces with them. This is a similar situation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜