2010-11-15 103 views
1

我有一個帶有訂單和退款模型的Rails應用程序。訂購has_many:退款。一切都很好。我正在嘗試爲控制器中的退款邏輯編寫功能測試。這就是我現在所擁有的:使用摩卡測試關聯方法

test "should not process partial paypal refund for partially refunded order when refund total plus refund amount is greater than order total" do 
    set_super_admin_login_credentials 
    o = Order.new 
    o.stubs({:id => 1234567, :source => "PayPal", :total => 39.95, :user => users(:dave)}) 
    Order.stubs(:find).with(1234567).returns(o) 
    get :refund, {:order_id => 1234567} 
    assert_equal o, assigns(:order) 
    o.refunds.build.stubs({:amount => 1.0}) 
    o.refunds.build.stubs({:amount => 30.00}) 
    assert_raise do 
     post :refund, {:order_id => 1234567, :refund_amount => 10.00} 
    end 
end 

和Controller,退款方法是這樣的:

def refund  
    @order = Order.find(params[:order_id]) 
    return if request.get? 

    amount = params[:refund_amount].to_f 
    raise "Cannot refund order for more than total" if (@order.refunds.sum(&:amount) + amount) 
    # Do refund stuff 
end 

一些注意事項:

  1. 我立足的o.refunds.build位在Ryan Bates' Railscast.如果這不正確或不再相關,那是有用的信息。

  2. 我見過很多關於如何實際執行sum方法的衝突信息,其中一些是&,另一些則沒有。在script/console&爆炸,但沒有它,我得到一個實際的總和。在我的控制,但是,如果我從&:amount:amount切換,我得到這個消息:NoMethodError: undefined method +」爲:金額:Symbol`

我覺得有一些概念上的信息丟失,而不是一個錯誤的地方,所以我會欣賞一些指針。

回答

1

終於想出了這個問題。我將作爲一個空關聯來存儲,而不是將它留在nil中,以便Rails能夠處理其他一些方法。所以,當我改變一個,另一個會失敗。智慧字:Enumerable#sumActiveRecord::Associations::AssociationCollection#sum採用完全不同的參數。 :)

因此,通過更改存根:refunds => []using a string for the field namesum我得到的東西恢復正常。所以,這裏是以上代碼的功能版本:

test "should not process partial paypal refund for partially refunded order when refund total plus refund amount is greater than order total" do 
    set_super_admin_login_credentials 
    o = Order.new 
    o.stubs({:id => 1234567, :source => "PayPal", :total => 39.95, :user => users(:dave)}) 
    Order.stubs(:find).with(1234567).returns(o) 
    get :refund, {:order_id => 1234567} 
    assert_equal o, assigns(:order) 
    o.refunds.build.stubs({:amount => 1.0}) 
    o.refunds.build.stubs({:amount => 30.00}) 
    assert_raise do 
     post :refund, {:order_id => 1234567, :refund_amount => 10.00} 
    end 
end 

def refund  
    @order = Order.find(params[:order_id]) 
    return if request.get? 

    amount = params[:refund_amount].to_f 
    raise "Cannot refund order for more than total" if (@order.refunds.sum('amount') + amount) 
    # Do refund stuff 
end