Mock functions in Jest provide controlled replacements for real functions during testing. They help you isolate units of code, verify interactions, and assert behavior without side effects.
By using Jest mocks, teams improve test reliability, speed, and clarity while avoiding unpredictable dependencies from databases, APIs, or random generators.
| Aspect | Description | Benefit | Example Use Case |
|---|---|---|---|
| Isolation | Replace real implementations with controllable versions | Focus tests on the unit in scope | Mocking a network client to simulate responses |
| Tracking | Capture calls, arguments, and instances | Validate integration patterns without relying on side effects | Ensuring a logger was called with expected data |
| Timing | Synchronous or async control via resolved/rejected promises | Test loading and error states deterministically | Mocking setTimeout to fast-forward asynchronous flows |
| Configuration | ModuleName with jest.genMockFromModule or manual implementations | Align mock shape with production code | Mocking filesystem methods in server utilities |
Manual Mock Function Creation
Using jest.fn() for inline control
Use jest.fn() to create lightweight mock functions inline in tests. You can define return values with .mockReturnValue and simulate side effects with implementation callbacks.
Custom mock modules for shared behavior
Define manual mocks in a __mocks__ folder next to the original module. Export deterministic implementations so multiple test files reuse the same mocked logic consistently.
Automatic Mocks with jest.mock
Module-level hoisting and factory control
Call jest.mock('module-name') at the top level to hoist an automatic mock. Jest replaces the module with a mock factory, preserving the original interface while neutralizing side effects.
Custom factory overrides for specific shapes
Provide a factory function to jest.mock when you need slight variations of a mock across test files. This keeps the contract realistic while allowing tailored behavior per suite.
Mock Function API and Matchers
Call tracking with getMockState
Inspect mock.calls, mock.instances, and mock.thisValues to verify how functions were invoked. Combine these properties with matchers to assert patterns like call order and receiver context.
Resolver and rejection control
Use mockResolvedValue and mockRejectedValue to simulate promise outcomes cleanly. This supports testing async components, hooks, and services without flaky waits or real async work.
Best Practices and Maintenance
- Prefer explicit mock contracts that mirror real function signatures
- Limit manual overrides to cases where automatic mocks are insufficient
- Centralize mock definitions in __mocks__ to reduce test duplication
- Validate call patterns with precise matchers instead of brittle index checks
- Document intentional deviations from real behavior to aid future maintainers
FAQ
Reader questions
How do I ensure a mock is used instead of the real module?
Use jest.mock('module') at the top of the test file and reference the module inside beforeEach or test blocks to guarantee the mock factory is applied before imports execute.
Can I restore original implementations between tests?
Call jest.restoreAllMocks() in afterEach to reset mock states, or use mockRestore on individual spies to revert functions to their original implementations automatically.
What is the difference between jest.fn() and jest.spyOn?
jest.fn() creates a brand new mock function, while jest.spyOn wraps an existing method on an object so you can track calls and temporarily replace behavior without losing the original reference.
How do I simulate rejected promises for error handling tests?
Use mockRejectedValue on the mock function or throw inside an async implementation to trigger catch paths and verify error boundaries gracefully.