Mocking indirect dependencies with Jest

Viewed 762

I am new to Jest and unit testing and I am not sure how to handle mocking in case of relatively deep invocation structures. Let's say we have the following app structure:

enter image description here

Given the grey classes (axios and cache) are external, 3rd party modules, I need to write unit tests for Domain.createUser and Backend.postUsers methods.

I have clear that within the Backend.postUser tests I need to mock axios.

In case of Domain.createUser, I would certainly mock cache, but I am not sure what to do with its second dependency.

Should I just mock Backend.postUser (as a direct dependency) or somehow indirectly mock just axios (as external dependency)?

Or both approaches work in different setups?

If so, what criteria should I use to make decision what is the best strategy?

1 Answers

Unit testing is all about units. The goal is to find defects in, and verify the functioning of separately testable software units. Usually, unit tests are done in isolation from the rest of the system, meaning that all the dependencies of the unit are mocked.

The size of a unit is entirely up to you. If you decide to mock axios when testing Domain.createUser, your unit is the combination of Domain.createUser and Backend.postUser. If you mock Backend.postUser instead, you reduce your unit to just Domain.createUser. You could even decide to mock nothing, increasing the size of your unit to your entire system.

However, a unit test that covers the entire system doesn't say much. If the unit test fails, the only thing you know is that there's an error in your system. There's no indication as to where in the system that might be. If the unit was much smaller, say, a single function, searching for the bug will be a lot easier. That's why, in practice, you start writing unit tests for the smallest testable component.

In your question you state that you want to test Domain.createUser, so that will be your unit. All dependencies of that unit should be mocked, so you'll mock Backend.postUser, which will be tested in another test.

If for whatever reason it wouldn't be possible to test Backend.postUser separately, it would be better to test Domain.createUser and Backend.postUser together in a single unit. Then you'll only mock cache and axios, since those are the direct dependencies of this unit. But usually it's preferred to test both separately.

Related