Prefer using verifying doubles over normal doubles.

When it comes to writing tests with doubles, the use of verifying doubles is generally preferred over normal doubles. Verifying doubles help ensure that the behavior being tested is executed correctly by verifying that the expected interactions occur.

Doubles in testing are objects that mimic the behavior of real objects. They are often used to replace dependencies in order to isolate the code under test and simulate different scenarios.

With normal doubles, you specify the expected method calls and return values, but they don’t verify that the interactions actually occurred. This means that if a method is not called or called with incorrect arguments, the test can still pass without any failure. This could lead to false positives where the test passes even though the expected behavior is not happening.

On the other hand, verifying doubles allow you to specify the expected interactions and will raise an exception if those interactions do not occur as expected. Verifying doubles add an extra layer of confidence that the tested code is interacting correctly with its dependencies.

Here’s an example to illustrate the use of verifying doubles. Let’s say we have a class named “OrderProcessor” that depends on an external “PaymentGateway” object. We want to test the “OrderProcessor” class in isolation by replacing the real “PaymentGateway” object with a double.


class OrderProcessor
  def initialize(payment_gateway)
    @payment_gateway = payment_gateway
  end
  
  def process_order(order)
    # Perform some operations
    @payment_gateway.charge(order.total_amount)
  end
end

RSpec.describe OrderProcessor do
  let(:payment_gateway) { instance_double("PaymentGateway") }
  let(:order) { double("Order", total_amount: 100) }

  subject { described_class.new(payment_gateway) }
  
  it "charges the correct amount using the payment gateway" do
    expect(payment_gateway).to receive(:charge).with(100)
    subject.process_order(order)
  end
end
  

In this example, we use an instance double for the “PaymentGateway” class as the dependency of “OrderProcessor”. The instance double verifies that the “charge” method is called with the expected argument, which is the total amount of the order. If the method is not called or called with a different argument, an exception will be raised and the test will fail.

By using verifying doubles, we can have more confidence in the behavior of our code and ensure that it interacts correctly with its dependencies, making the tests more reliable.

Leave a comment