1

私は注文モデルを持っています。これは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のスタブ化とモック化の概念を完全には理解していません。私は何を間違っていますか?

4

1 に答える 1

1
@order = mock_model(Order)

ここでは、空白のキャンバスだけであるモック オブジェクトを作成します。何かを設定したい場合は、 :payments に何かで応答するように指示する必要があります。この場合、1 つのエントリを持つ配列 (モック Payment オブジェクト)

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

それはあなたをさらに先へと導きます。その他の注意事項:

  • この期待Payment.should_not_receive(:new)があなたの行動をテストするかどうかはわかりません。あなたは実際に Payment.new ではなく Payment.create を呼び出します
  • @order を返すために Order.find をスタブ化していると思いますが、ここには示されていませんよね?
  • 通常、@order を次のように単純化します。

ここでは、 #payments が空でない配列を返し、内容は気にしないと言います。

@order = mock_model(Order)
@order.stub(:payments) { [stub] }
于 2012-06-18T12:44:34.290 に答える