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 stubbing 和 mocking 的概念。我怎么了?

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.create,而不是 Payment.new
  • 我希望您在某个地方删除 Order.find 以返回 @order,但这没有在这里显示,对吧?
  • 我通常会将您的@order 简化为以下内容:

这里我们说#payments 返回一个非空数组,我们不关心内容。

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