Choosing Jest Mock Cleanup: clearMocks, resetMocks, restoreMocks
Choose between Jest clearMocks, resetMocks, and restoreMocks for automatic mock cleanup in JavaScript and TypeScript tests.
15 Jun 2026, 05:27 UTC

Problem and takeaway
A test passes when you run it alone but fails in the full suite. The usual suspect is a mock that carries over call counts, return values, or a replaced method from the previous test.
Jest can clean up mocks automatically before every test with three boolean configuration keys: clearMocks, resetMocks, and restoreMocks. Use clearMocks to reset call history while keeping a mock’s implementation, resetMocks to also wipe the implementation, and restoreMocks only for methods replaced with jest.spyOn(). None of these reset imported module state.
Decision and constraints
Decision: which cleanup keys to enable in your Jest configuration file. Constraints: the values apply globally to every test file unless you override them in beforeEach or afterEach; they assume a recent Jest release (Jest 27 or later); and they do not reset the module registry, so imported module state can still leak between tests.
Compare the supported cleanup options
| Option | Method Jest calls | What is cleared or reset | What remains | Best for |
|---|---|---|---|---|
clearMocks: true | mockClear() on each mock | Call counts, instances, and contexts | Mock implementation and return values | Resetting call history without losing mock behavior |
resetMocks: true | mockReset() on each mock | Everything clearMocks does, plus the mock implementation | Nothing; mocked functions return undefined until redefined | Plain jest.fn() mocks and automocks that need a blank slate per test |
restoreMocks: true | mockRestore() on each spy | The original object method, for mocks created with jest.spyOn() | Plain jest.fn() mocks and jest.mock() automocks are untouched | Restoring real methods after spying on them |
resetMocks includes clearing behavior, so enabling both clearMocks and resetMocks is redundant. restoreMocks is independent and spy-specific.
Trade-offs
clearMocks
This is the gentlest automatic cleanup. Call history disappears before each test, but a mock’s implementation survives. That is useful when you define mockReturnValue once in beforeAll and only want to assert toHaveBeenCalledTimes per test. The risk is stale return values: if one test changes a mock’s result, the next test sees the change unless you reset it manually.
resetMocks
This gives the strongest isolation for plain mocks. Every mocked function starts without an implementation, so tests cannot accidentally rely on a return value from an earlier test. The downside is that tests break if they expect a mocked module to keep its implementation across tests in the same file. You must redefine implementations in each test or in beforeEach.
restoreMocks
Use this when you spy on real methods with jest.spyOn(). Without it, a replaced method stays replaced after the test ends, which can corrupt later tests or other modules that import the same object. restoreMocks does nothing for standalone jest.fn() mocks or jest.mock() automocks, so combine it with clearMocks or resetMocks if your suite uses both styles.
What none of them do
These options do not reset Jest’s module registry. If an imported module mutates its own top-level state, that state can still leak between tests. Use resetModules: true separately for that problem.
Configure Jest
Edit your Jest configuration file, typically jest.config.js in the project root. No special permissions are required beyond write access to the file.
module.exports = {
clearMocks: true,
// resetMocks: true,
// restoreMocks: true,
};
Enable only one of clearMocks or resetMocks; enabling both is redundant. You can combine either with restoreMocks if your tests use jest.spyOn(). For TypeScript projects using jest.config.ts, export the same object with the appropriate type.
Validate the setting
Run the following from the project root, where npx resolves to your locally installed Jest:
npx jest --showConfig
Inspect the serialized output for clearMocks, resetMocks, and restoreMocks. Expected check: the keys you enabled show true, and the others show false.
To confirm behavior, add a temporary assertion in a test file:
beforeEach(() => {
expect(myMock).not.toHaveBeenCalled();
});
With clearMocks or resetMocks enabled, the assertion should pass. Disable the option, run the same suite, and confirm the assertion can fail when call history persists. Risk: changing a global config flag affects every test file, so run the full suite after toggling and before merging.
You can also copy your config, toggle one flag at a time, and run npx jest --config jest.config.tmp.js to observe which tests fail because of lost implementations or missing spy restoration.
Limitations and rollback
Global cleanup flags apply to all test files. If one file needs manual control, disable the flag and use beforeEach or afterEach explicitly in that file. These options do not reset module state; pair with resetModules if imported modules leak state.
Rollback: revert the changed boolean to false or remove the key from the configuration file, then restart Jest. No database or migration state is involved.
Check installed version with npx jest --version; defaults are stable in recent releases, but very old versions may behave differently.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.