Skip to main content

How to Reset, Clear, and Restore Mocks in Jest in JavaScript

In Jest, maintaining test isolation is critical. A mock's behavior or call history from one test should not leak into another, as this can lead to flaky and unpredictable test results. To ensure each test runs from a "clean slate," Jest provides several functions to reset mocks to their initial state.

This guide will clarify the three distinct levels of resetting mocks: clearing, resetting, and restoring. You will learn the difference between mockClear(), mockReset(), and mockRestore(), and how to configure Jest to perform these actions automatically before each test.

The Core Problem: Test Isolation

When you use a mock function across multiple tests, its internal state (like the number of times it was called) persists.

Example of code with problems:

const myMock = jest.fn();

test('first test', () => {
myMock();
expect(myMock).toHaveBeenCalledTimes(1); // Passes
});

test('second test', () => {
// This test fails because myMock was already called in the first test.
// The call count is now 2, not 1.
myMock();
expect(myMock).toHaveBeenCalledTimes(1); // Fails! Expected 1, received 2.
});

To fix this, we need to reset the mock's history between tests.

Three Levels of Reset: A Quick Comparison

Jest offers three "levels" of resetting. Understanding the difference is key to choosing the right one.

MethodWhat it ResetsWhen to Use
mockClear()Resets usage stats (.mock.calls, .mock.instances).The most common case. Use when you want a clean slate for toHaveBeenCalled() checks but want to preserve a mocked implementation.
mockReset()Does everything mockClear() does, plus removes any mocked implementations or return values.Use when you need to completely reset a mock to a simple jest.fn(), wiping both its usage and its behavior.
mockRestore()Does everything mockReset() does, plus restores the original function implementation.Only for spies (jest.spyOn()). Use when you want to completely undo the mock and revert to the real function.

Level 1: Clearing Mock Usage (.mockClear())

This is the most common form of reset. It wipes the call history of a mock but leaves any custom implementation intact.

Solution: By calling mockClear() in a beforeEach or afterEach hook, you ensure each test starts with a fresh call history.

const myMock = jest.fn();

beforeEach(() => {
myMock.mockClear(); // Clears the call history before each test
});

test('first test', () => {
myMock();
expect(myMock).toHaveBeenCalledTimes(1); // Passes
});

test('second test', () => {
myMock();
expect(myMock).toHaveBeenCalledTimes(1); // Passes now!
});
note

To clear all mocks at once, you can use jest.clearAllMocks() in the hook.

Level 2: Resetting Mock Implementation (.mockReset())

This is a "harder" reset. It clears the call history and removes any fake implementation you might have provided with mockReturnValue() or mockImplementation().

Solution: this is useful when different tests need to provide different mock implementations.

const myMock = jest.fn();

beforeEach(() => {
myMock.mockReset(); // Resets the mock to its initial state
});

test('mock returns a specific value', () => {
myMock.mockReturnValue('tutorialreference.com');

expect(myMock()).toBe('tutorialreference.com');
expect(myMock).toHaveBeenCalledTimes(1);
});

test('mock is a simple, empty function', () => {
// Because of mockReset(), the previous mockReturnValue is gone.
expect(myMock()).toBe(undefined);
expect(myMock).toHaveBeenCalledTimes(1);
});

To reset all mocks this way, you can use jest.resetAllMocks().

Level 3: Restoring the Original Implementation (.mockRestore())

This is the "hardest" reset and is only relevant for mocks created with jest.spyOn(). It completely undoes the spy, restoring the original, non-mocked function.

Solution:

const video = {
play() {
return 'original implementation';
},
};

let playSpy;

beforeEach(() => {
// If a spy already exists, restore it before creating a new one.
if (playSpy) {
playSpy.mockRestore();
}
});

test('play() implementation is mocked', () => {
playSpy = jest.spyOn(video, 'play').mockImplementation(() => 'mocked implementation');

expect(video.play()).toBe('mocked implementation');
});

test('play() has its original implementation', () => {
// Because of mockRestore(), the spy is gone.
// We are now calling the original video.play() method.
expect(video.play()).toBe('original implementation');
});
note

To restore all spies at once, you can use jest.restoreAllMocks().

Automating Resets: Configuration and Command-Line

Instead of adding a beforeEach hook to every test file, you can configure Jest to do this for you automatically. This is the recommended best practice for maintaining consistency across a project.

jest.config.js

Add one of the following boolean properties to your jest.config.js file:

// jest.config.js
module.exports = {
// Option 1: Clears mocks before each test (Level 1)
clearMocks: true,

// Option 2: Resets mocks before each test (Level 2)
resetMocks: true,

// Option 3: Restores mocks before each test (Level 3)
restoreMocks: true,
};
note

You can only set one of these to true. resetMocks is often the best balance of safety and isolation.

Command-Line Flags

You can also enable this behavior for a single run using a command-line flag:

# Level 1
npx jest --clearMocks

# Level 2
npx jest --resetMocks

# Level 3
npx jest --restoreMocks

Conclusion

Properly resetting mocks is essential for reliable tests. Jest provides a clear hierarchy of tools for this purpose.

  • mockClear() is for resetting call history while keeping a mocked implementation.
  • mockReset() is for wiping both call history and the implementation.
  • mockRestore() is for completely undoing a jest.spyOn() and restoring the original function.

For most projects, configuring resetMocks: true in your jest.config.js provides the best balance of safety and convenience, ensuring every test starts with a completely fresh set of mocks.