2012-06-18 40 views
1

我有一個訂單模型,其中has_many付款和結帳控制器。如果沒有付款,控制器應該創建新的付款。扼殺或嘲弄Foo.has_many酒吧並預先填充酒吧

private 
# Helper method allows calling from several controller-callbacks. 
def add_payment_if_not_exists 
    if @order.payments.empty? 
    Payment.create(...) 
    end 
end 

,現在我想在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 

符合規範這種行爲不過,這將引發

Failure/Error: @order.payments << mock_model(Payment).as_null_object 
    Mock "Order_1003" received unexpected message :payments with (no args) 

不知怎的,我還是不神交rspecs磕碰和完全嘲諷的概念。我錯在哪裏?

回答

1
@order = mock_model(Order) 

在這裏你創建一個模擬對象,只是一個空白的畫布。如果你想設置的東西,你應該告訴它迴應:付款與某事。在這種情況下,具有1個條目的數組(模擬支付對象)

@order.stub(:payments) { [mock_model(Payment).as_null_object]} 

這會讓您走得更遠。其他說明:

  • 我不確定這個期望Payment.should_not_receive(:new)測試你的行爲。您實際上撥打Payment.create,而不是Payment.new
  • 我希望您將Order.find留在某處以返回@order,但這裏沒有顯示,對吧?
  • 我通常會簡化@order以下幾點:

這裏我們說#payments返回一個非空數組,我們不關心的內容。

@order = mock_model(Order) 
@order.stub(:payments) { [stub] } 
+0

謝謝。殘根是我忘記的東西。我簡化了代碼。現在我實際上在塊之前將大部分數據存儲在數據庫中,因爲我正在Spree中進行測試,Spree是緊耦合模型的spagetti-monster。但我正在重構我的測試以更頻繁地使用存根和嘲諷。 – berkes