Understanding Jest Mocks

Photo by Ferenc Almasi on Unsplash.

Jest is a powerful toolkit for testing JavaScript and TypeScript code. It's an all-in-one test runner, mocking framework, and assertion library. Without Jest, you might need to stitch together a separate library for each of these testing needs.

But I've always struggled to navigate Jest's complex mocking functionality. A long list of factors determine whether Jest replaces a module with fake logic (mocked) or executes the actual module (unmocked). To figure it out, I created a test project.

For the following questions, imagine you want to test a file which imports some-dependency — which could be a local file, an npm package, or a built-in Node.js module.

1. Explicit unmock

Does the test call jest.unmock('some-dependency') or jest.dontMock('some-dependency')?

If no, continue to the next section.

If yes, some-dependency will not be mocked.

2. Explicit mock

Does the test call jest.mock('some-dependency') or jest.doMock('some-dependency')?

If no, continue to the next section.

If the test uses the mock functions API like mockImplementation(), mockReturnValue(), or mockResolvedValue() to specify the mock's behavior, some-dependency will use that behavior.

Or if the jest.mock('some-dependency') / jest.doMock('some-dependency') call includes the factory parameter, some-dependency will use the behavior specified by factory.

Or if some-dependency has a manual mock (a file in the appropriate /__mocks__/ directory), some-dependency will use the behavior specified by that manual mock.

Otherwise Jest will autogenerate a default mock of some-dependency using the substitution approach described in the docs for jest.createMockFromModule().

3. Core module

Is some-dependency a core Node.js module?

If no, continue to the next section.

If yes, some-dependency will not be mocked.

4. Automocking

Is Jest automocking enabled? Automocking may be enabled with automock: true in the Jest configuration, or by calling jest.enableAutomock() in the test.

If no, continue to the next section.

If some-dependency has a manual mock (a file in the appropriate /__mocks__/ directory), some-dependency will use the behavior specified by that manual mock.

Otherwise Jest will autogenerate a default mock of some-dependency using the substitution approach described in the docs for jest.createMockFromModule().

5. Local module

Is some-dependency a local file?

If no, continue to the next question.

If yes, some-dependency will not be mocked.

6. Manual mock

Does some-dependency have a manual mock (a file in the appropriate /__mocks__/ directory)?

If no, some-dependency will not be mocked.

If yes, some-dependency will use the behavior specified in the manual mock.

Drew

Drew

Hi! I'm Drew, the Wimpy Programmer. I'm a software developer and formerly a Windows server administrator. I use this blog to share my mistakes and ideas.