When to Use a Test Double
Not all interactions will use test doubles. My rule of
thumb is to use the real code when you can and use a
test double when you must. You will need to use
judgment to decide when to fake and when not to fake.
For example, if the CUT uses a linked list as one of
its collaborators, there is no need to use a fake
linked list. Use the real one. The test case consults
the linked list during the verify stage
of the Four-Phase Test pattern to see whether the right
additions, deletions, and modifications were made to
the linked list.
Here are some common reasons to use a test double:
- Hardware independence
-
Having test doubles for hardware interactions will
allow testing independently from the hardware. It
also provides the ability to feed a wide variety of
inputs into the core of the system that may be very
difficult or time-consuming to do in the lab or
field.
- Inject difficult to produce input(s)
-
Some computed or hardware-generated event scenarios
may be difficult to produce. By adjusting the return
result of a test double, the CUT might have all it
needs to trigger some unlikely execution path.
- Speed up a slow collaborator
-
If tests don’t run fast, you will likely stop
running them as often as you should. A slow
collaborator, such as a database, a network service, or
some number crunching, can be faked out by returning
a result controlled by the test case, speeding up
the test.
- Dependency on something volatile
-
The classic example of a volatile collaborator is
the clock. You have some event that is supposed to
happen at 8:42 a.m.—either you get one chance a day or
you have to reset the clock. But with a double
standing in for the clock, it can be 8:42 a.m.—or
the last day of leap year—whenever you want.
- Dependency on something under development
-
Design often encompasses unknown areas,
especially when hardware and software are
concurrently developed. As you approach an area of
the unknown, develop a test double with the
interface that best meets the CUT’s needs. Progress
on the CUT can continue, while at the same time
exploring the CUT’s needs of the currently
unimplemented service.
- Dependency on something that is difficult to configure
-
If a DOC is difficult to set up and get into one or more desired states,
it may be best to substitute a test double.
A database is a good example of a DOC that you could test with but is difficult to set up.
Choosing to use test doubles for the CUT is not an all-or-nothing proposition. Most often you will have a
variety of real and fake collaborators, as shown in
Figure
Using test doubles and real collaborators
.
Also, for some tests you will want to use the production code collaborator,
and for others you will want the test double.