通过设置预期的消息期望来进行模拟

下面的例子使用 expectreceive 来模拟 OrderCreditCardService 的调用,这样只有在调用完成而不必实际调用时,测试才会通过。

class Order
  def cancel
     CreditCardService.instance.refund transaction_id
  end
end

describe Order do
  describe '#cancel' do
    it "refunds the money" do
      order = Order.new
      order.transaction_id = "transaction_id"
      expect(CreditCardService.instance).to receive(:refund).with("transaction_id")
      order.cancel
    end
  end
end

在这个例子中,模拟是 CreditCardService.instance 的返回值,它可能是一个单例。

with 是可选的; 如果没有它,任何对 refund 的调用都会满足期望。and_return 可以给出一个返回值; 在这个例子中它没有被使用,所以调用返回 nil