Test Doubles for the win

When writing unit or contract tests you encounter situations in which you need mock things. Given you want to test a method in Class A that uses a collaborator (class / interface B). When you don’t want to use the real implementation of class / interface B, then you need to have something that imitates the behavior of that collaborator. This is generally known as the practice of mocking. A better term for mocking however is the term Test Double. A mock is just one instance of a Test Double, but there are more variations (stub, spy, etc). The term Test Double comes from the book xUnit Test Patterns: Refactoring Test Code. Just as an actor does not do his own stunts but has a stunt double, so a Test Double takes the place of a collaborator. Reasons for using a Test Double may vary. Having isolated tests that are not coupled to the implementation of collaborators – and therefore only fail if the unit under test does not display the desired behavior – is one reason.

Test Doubles
Real implementation versus Test Double
Another reason could be that a collaborator is not implemented at all or costs money to use (think of an address lookup service that costs 5 cent per request). When to use or not to use a Test Double is up for debate, widely discussed and out of scope for this series of posts. This series focuses on the type of Test Doubles and their implementations.

According to xUnit Test Patterns we have five types of Test Doubles.

  • A Dummy Object is a placeholder object that is passed to the SUT as an argument (or an attribute of an argument) but is never actually used.
  • A Test Stub is an object that replaces a real component on which the SUT depends so that the test can control the indirect inputs of the SUT. It allows the test to force the SUT down paths it might not otherwise exercise.
  • A Test Spy, which is a more capable version of a Test Stub, can be used to verify the indirect outputs of the SUT by giving the test a way to inspect them after exercising the SUT.
  • A Mock Object is an object that replaces a real component on which the SUT depends so that the test can verify its indirect outputs.
  • A Fake Object (or just “Fake” for short) is an object that replaces the functionality of the real DOC with an alternative implementation of the same functionality.

My conviction is that as a tester you should at least know what these Test Doubles are used for and what they could look like. Especially in a test first context, knowledge of Test Doubles is of critical importance. In the next post I will go in on the Dummy Object.

Author: David Baak

To code or not to code? That's true.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.