2011-09-02 85 views
0

我正在研究电子商务系统并熟悉RSpec。使用RSpec,should_receive和create来测试setter?

订单有关联的付款。订单完成后,它开始通过我们的支付网关处理付款。

下面是规范,适当的方法和失败消息。

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 

这里是Order类。

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

第二个规范失败,声称:source =永远不会被收到。有了订单,它只是说这个过程!被称为乱序。没有命令,它表示它期望:来源=一次,但从未收到它。我明白为什么命令应该在那里,但只是想清楚它声称:source =从未被接收。

是创建!没有调用source =?测试的适当方法是什么,以确保正确设置付款来源?

回答

0

我会说你的it "creates a payment"规范就够了。 create!的行为责任应该在专门为它写的规范中。

如果你真的想确保create!是做什么它应该,也许尝试让process_payment保存到数据库中,然后调用Payment.last来获得新的记录,并检查它的性能。但我认为这会过度。

想想这样,当你编写控制器规格时,你不会再次测试模型的所有行为;你只需测试你的控制器与他们的接口。这是一个类似的情况。

+0

够公平的。将payment.should_receive(:process!)折叠到该代码段中? –

+0

是的,抱歉。我昨晚应该抓到了。 – patrickmcgraw