Call Montréal, Canada 524-949-6869

Blog

Friday, March 9, 2012

Testing Terminology: Spies, Stubs and Mocks

When referring to the definitions of Spies, Stubs and Mocks I like to return to XUnit Test Patterns:

  • Test Spy: "We use a Test Double to capture the indirect output calls made to another component by the SUT for later verification by the test."
  • Test Stub: "We replace a real object with a test-specific object that feeds the desired indirect inputs into the SUT."
  • Mock Object: "We replace an object the SUT depends on with a test-specific object that verifies it is being used correctly by the SUT."

You may have noticed that a Spy and Mock seem to have similar definitions, and do serve similar purposes, however Mocks specify expectations up-front and don't require assertions in contrast to Spies, that verify after the fact. Here's an example that compares Rspec Mocks with Bourne's Spies:

SUT is an abbreviation for System Under Test.

describe Transfer, "using Rspec Mock" do
  it "deposits amount into destination account" do                                            
    source_account      = stub("source account", withdraw: 10)
    destination_account = mock("destination_account")

    destination_account.should_receive(:deposit).with(10)

    transfer = Transfer.new(source_account, destination_account)    
    transfer.call
  end                                             
end

describe Transfer, "using Bourne Spy" do
  it "deposits amount into destination account" do                                            
    source_account      = stub("source account", withdraw: 10)
    destination_account = mock("destination_account")

    transfer = Transfer.new(source_account, destination_account)    
    transfer.call 
    
    destination_account.should have_received(:deposit).with(10) 
  end                                             
end 

The above patterns are collectively know as Test Doubles: "We replace a component on which the SUT depends with a test-specific equivalent." Rspec's built-in mocking library includes a double method/alias, see An Example using RSpec double, mock, and stub.

Double-Ruby (RR) is another example of a test double framework implemented in Ruby.

Developing Ruby on Rails applications and Radiant-based Content Management Systems in Montréal. Contact Firsthand.