When you call jest.mock('./module') without a factory or manual mock file, Jest automatically generates a mock version. This lesson explains exactly what auto-mocking does and its trade-offs.
What Auto-Mocking Generates
Auto-mocking inspects a module's real exports and creates a mock version with the same shape: every function becomes an empty jest.fn() that returns undefined, and non-function exports (like plain objects or constants) are typically preserved or deeply mocked depending on their structure.
This is useful as a starting point, but auto-mocked functions do nothing until you explicitly configure them with .mockReturnValue() or similar, inside your test.
// mathUtils.js
module.exports = {
add: (a, b) => a + b,
PI: 3.14159,
};
// test file
jest.mock('./mathUtils');
const mathUtils = require('./mathUtils');
console.log(mathUtils.add(2, 3)); // undefined — auto-mocked, no real logic
mathUtils.add.mockReturnValue(5);
console.log(mathUtils.add(2, 3)); // 5 — now configured
The auto-mocked add function exists and is trackable, but returns undefined until explicitly configured.
automock: true makes Jest auto-mock every module import across the entire suite by default.
This is rarely enabled because it requires explicitly un-mocking (jest.unmock()) anything you want to test for real.
Most projects leave automock at its default (false) and call jest.mock() selectively per test file.
Auto-mocking still respects manual mocks in __mocks__ folders if they exist.
Auto-Mocking Cheat Sheet
How auto-mocking behaves for different export types.
Export Type
Auto-Mocked Result
Function
Replaced with an empty jest.fn()
Class
Methods replaced with empty jest.fn()s
Plain object/constant
Usually preserved as-is
Module with a manual mock file
Manual mock used instead of auto-generated one
Why automock: true Is Rarely Used
Enabling automock project-wide sounds convenient, but it means every single dependency (including trivial internal utilities) is mocked by default, forcing you to explicitly jest.unmock() anything you actually want to run for real. Most teams find selective, explicit jest.mock() calls per test file easier to reason about.
Explicit jest.mock() calls make it obvious, per file, what's faked.
Global automock hides which dependencies are real vs. fake at a glance.
Debugging "why does this return undefined" issues is harder with global automocking.
Auto-Mocking Combined with Manual Mocks
If a __mocks__ folder defines a manual mock for a module, calling jest.mock('./module') uses that manual mock instead of generating a generic auto-mock — auto-mocking is really the fallback behavior when no manual mock exists.
jest.mock('./emailClient'); // uses src/__mocks__/emailClient.js if it exists
jest.mock('./mathUtils'); // falls back to auto-mocking since no manual mock exists
Common Mistakes
Expecting an auto-mocked function to have real logic without configuring it first.
Enabling project-wide automock: true without understanding the un-mocking burden it creates.
Confusing auto-mocking (generated automatically) with manual mocking (explicitly written in __mocks__).
Not realizing a manual mock takes priority over Jest's auto-generated mock when both exist.
Key Takeaways
jest.mock('./module') with no factory or manual mock triggers auto-mocking.
Auto-mocked functions return undefined by default until explicitly configured.
Project-wide automock: true exists but is rarely used due to the extra un-mocking overhead.
Manual mocks in __mocks__ folders take priority over Jest's automatic mock generation.
Pro Tip
If an auto-mocked function's return value matters for your test, always configure it explicitly with .mockReturnValue() right after the mock is created — never assume the auto-generated behavior is enough.
You now understand automatic mocking. Next, learn practical patterns for mocking Node.js core modules.