This week we’re resuming the usual service of covering different topics on how to test code. Specifically we are going to talk about one of the most powerful and versatile techniques, namely test doubles. We paid lip service to them in the post about testing haberdashery as a useful technique for isolating parts of the code from each other so they can be tested separately from their dependencies. In this post we are going to go more depth on what they are and how they are used.
pretending to be someone else in a socially acceptable way
First a definition: A test double is an object that can take the place of a real object in a test. Let’s make this more concrete with an example:
In this example we have an interface
Database and an implementation of that interface
RealDatabase that we use in production. As we discussed in testing haberdashery if we are testing a class
SomeClass that depends on
Database we wouldn’t want to use a real implementation of the database in the test because then our test’s success or failure will not just depend on the correct behaviour of
SomeClass, but also on the correct behaviour of the database.
This is where test doubles become useful. In addition to the
RealDatabase we also have a
TestDoubleDatabase which implements the same interface and which can therefore be used anywhere where we expect a
Database, but which we will ensure will behave in a predictable way.
there’s impostors and then there’s mimes
To explain what predictable way means let’s cover how you implement a test double. There are primarily three kinds of doubles: stubs, mocks and fakes. Taking them one by one…
Stubs only return what you tell them to return and have no logic of their own. Their usefulness is in that they allow you to test different paths of your code by controlling what its dependencies return. If you were using some kind of framework to generate them they could look like this:
Mocks are an extension of stubs in that they can be configured to return specific values if needed, but they also allow you to assert that they have been called in a specific way as part of the test, e.g.:
Fakes are simpler implementations of the code in question that can be used in a test, e.g. an in-memory database instead of the actual db service.
You can find more information about test doubles in this article by Martin Fowler.
If you enjoyed the read, drop us a comment below or share the article, follow us on Twitter or subscribe to our #MetaBeers newsletter. Before you go, grab a PDF of the article, and let us know if it’s time we worked together.