Skip to content

Spys vs Doubles #97

@joshmfrankel

Description

@joshmfrankel

Arrange-Act-Assert

Spy

  • Permissive
  • expect(spy_object).to have_received(:method)
  • Doesn't fail if the spy_object calls an undefined method
it "processes a payment correctly" do
  payment_processor = spy
  allow(PaymentProcessor).to receive(:new).and_return(payment_processor)
  
  process_payment(amount: 100)
  
  # Easy to verify the complete flow
  expect(payment_processor).to have_received(:validate_amount!)
  expect(payment_processor).to have_received(:check_funds!)
  expect(payment_processor).to have_received(:process_transaction!)
  expect(payment_processor).to have_received(:send_receipt!)
end

Double

  • Strict
  • Fail whenever an undefined method is called on self
  • expect(double_object).to receive(:method)
it "processes a payment correctly" do
  payment_processor = double("PaymentProcessor")

  # Must declare all expected methods upfront
  expect(payment_processor).to receive(:validate_amount!)
  expect(payment_processor).to receive(:check_funds!)
  expect(payment_processor).to receive(:process_transaction!)
  expect(payment_processor).to receive(:send_receipt!)
  
  process_payment(amount: 100)
end

To replicate a spy you'd need to do something like:

it "processes a payment correctly" do
  payment_processor = double("PaymentProcessor")
  
  allow(payment_processor).to receive(:validate_amount!)
  allow(payment_processor).to receive(:check_funds!)
  allow(payment_processor).to receive(:process_transaction!)
  allow(payment_processor).to receive(:send_receipt!)

  process_payment(amount: 100)

  expect(payment_processor).to receive(:validate_amount!)
  expect(payment_processor).to receive(:check_funds!)
  expect(payment_processor).to receive(:process_transaction!)
  expect(payment_processor).to receive(:send_receipt!)
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions