Patterns to reduce unit test friction - 2 - Abstract external dependencies
The Problem
Your class has a dependency on something that is outside of your control. A simple scenario for this is the DateTime object, its quite common to need to simulate a different “Now” in your tests to the one that the rest of the system uses.
e.g.
And the test might look like:
So.. we have the current UtcDate being set inside the test method, but from outside we cannot control the value that we’re expecting, this is a bit of a pain, and solutions without controlling the datetime being set may lead to brittle tests (i.e. Any time within the last second would be fine, until for some reason the test takes longer than that to run, and fails).
The Solution
Encapsulate the external dependency in a wrapper that just provides the functionality that you require to use.
So in the date case, in its simplest form, you might have:
So now in our test we can replace the clock with a mock, and simulate the time.
When its applicable
This is most applicable when dealing with non-trivial things that you can’t mock, so pretty much anything talking to something external, that hasn’t got a mockable interface and therefore cannot simply be replaced in the test.
Granted DateTime might be a contrived example as you might not really care about the creation date in this case, but its actually quite a good representation of something thats not mockable or controllable , but you might want to control in an isolated way during a test.