The technique I am going to demonstrate is arguably not true DI, since the dependencies are still managed by the module using them. However, it solves the dependency problem for testing which is the focus of this article.
Why Do You Need DI?
At the most basic level, you need DI to avoid testing your dependencies. Not testing dependencies is a good idea for two reasons:
Your dependencies should already be tested. This applies to both external dependencies as well as from your own project. If an external dependency doesn’t have good testing, you probably shouldn’t be using it or you should help them and add some tests!
Dependencies can do too much. Since dependencies exist outside of your module’s control, they can perform actions your module shouldn’t be concerned with such as saving data, making web requests, or being algorithmically heavy.
Your tests will be less complicated and faster if you avoid tesing dependencies because of the reasons mentioned above.
Setting Up Your Code to Enable DI
To start off, put all dependencies which should not execute during
a test into an exported
Once you have the
deps object defined, you no longer reference the dependency
directly. Instead, you call the appropriate dependency on the
That’s all you need to make your dependencies testable in any context!
You will have the same level of testability across
node application using the
require syntax, and front end application using
import syntax without extra code.
deps Object in Your Tests
With your module exporting all of its dependencies, your tests can
easily mock or replace anything in the
beforeAll block is the most important piece of code. Because
we are using functions from the
deps object in our module code, we can
deps.longRunningFunction with anything we want before invoking
the module’s default function.
In this example, we are using Jest’s built in mock
It can produce a mock value to verify that our function returns the correct value and is called with the expected arguments.
The best part about testing this way is that we don’t have to worry about
specifications. Often times, spies don’t work the same for all module syntaxes.
In fact, we don’t have to use the mocks at all! We could write our
own function with custom validators and set it as