Notes On Test Doubles

Taxonomy of Terms

There's an inconsistent vocabulary for test-doubles. Gerard Meszaros provides a taxonomy in his Patterns book as follows. (SUT = software under test)

  • Test Double - We replace a component on which the SUT depends with a "test-specific equivalent."
  • Hard-Coded Test Double - Build the Test Double by hard-coding the return values and/or expected calls.
  • Test Spy - Use a Test Double to capture the indirect output calls made to another component by the SUT for later verification by the test.
  • Test-Specific Subclass - Add methods that expose the state or behavior needed by the test to a subclass of the System Under Test (SUT).
  • Mock Object - Replace an object the system under test (SUT) depends on with a test-specific object that verifies it is being used correctly by the SUT.
  • Configurable Test Double - Configure a reusable Test Double with the values to be returned or verified during the fixture setup phase of a test.
  • Test Stub - We replace a real object with a test-specific object that feeds the desired indirect inputs into the system under test.
  • Fake Object - Replace a component that the SUT depends on with a much lighter-weight implementation.

in addition I've seen reference to

  • Dummy Object - a dummy value that has no interesting behaviour but simply fulfils the type requirements.
  • Pseudo Object - a dummy value that throws exceptions for any method.

Critique

This taxonomy does not bring out the main dimensions on which they may vary or the relationships between the patterns. As a result, it is difficult to determine whether or not the set of pattens is in any sense complete and/or what the complete space of patterns is.

Dimensions

  • Implementation of methods: Complete, Partial or None.
    • Fake Object may provide a full or partial implementation of methods.
    • Dummy/Pseudo Object will implement no valid methods.
  • Proxying
    • A good implementation of a test spy is as a proxy
  • Control: Verifies, records or passive.
    • Mock objects verify the methods called and the pattern of calls.
    • Test Spies observe the calls.
    • Fake Objects are passive.
  • Flexibility: Hard coded, configurable or procedural.
    • Test Stubs are hard-coded.
    • Configurable test doubles and mock objects are configurable.
    • Fake objects are typically procedural.

Some patterns are clearly more significant than others:

  • Mock Object captures the notion of verifying the calls/call-pattern.
  • Test Spy captures the notion of recording calls for later analysis.
  • Hard-Coded vs Configurable Test Double vs Fake captures the idea of canned, inflexible but tightly controlled activity versus programmed, flexible but not controlled activity