PRACTICAL GUIDE / Jest clear reset restore mocks

Jest clearAllMocks vs resetAllMocks vs restoreAllMocks

Jest clear reset restore mocks explained: compare what each API clears, what survives, how spies differ, and which cleanup belongs in each test.

By The Testing AcademyUpdated July 25, 202618 min read
All field guides
In this guide11 sections
  1. What Is the Difference Between the Three Jest Cleanup APIs?
  2. What State Does a Jest Mock Hold?
  3. What Does jest.clearAllMocks Clear?
  4. What Does jest.resetAllMocks Reset?
  5. What Does jest.restoreAllMocks Restore?
  6. Which Cleanup API Should You Use?
  7. Follow a Numbered Mock-Cleanup Decision Workflow
  8. Build a Stateful Example from the Repo Challenge
  9. How Do the Jest Config Options Change the Suite?
  10. Frequently Asked Questions About Jest Mock Cleanup
  11. Does jest.clearAllMocks remove mock implementations?
  12. Does jest.resetAllMocks restore spied methods?
  13. Does jest.restoreAllMocks work on jest.fn?
  14. Should cleanup run in beforeEach or afterEach?
  15. Can I enable cleanup in Jest config?
  16. Is jest.resetModules the same as jest.resetAllMocks?
  17. Conclusion: Reset Only the State the Test Changed

What you will learn

  • What Is the Difference Between the Three Jest Cleanup APIs?
  • What State Does a Jest Mock Hold?
  • What Does jest.clearAllMocks Clear?
  • What Does jest.resetAllMocks Reset?

Jest clear reset restore mocks are three cleanup levels for three different forms of state. jest.clearAllMocks() removes recorded usage data while keeping fake behavior. jest.resetAllMocks() also resets mock implementations. jest.restoreAllMocks() reinstates originals for supported spies and replaced properties. The correct choice depends on what the next test must not inherit.

The names are similar enough to encourage trial and error, but a state model makes the decision mechanical. This guide uses the javascript-testing-jest-mocks-spies-quiz entry in src/db/seed-data/challenges/expansion-js-ts.ts, whose title is jest.fn, spyOn, and the Three Resets, and verifies the API boundaries against the current Jest Object documentation, Mock Function API, and configuration reference.

What Is the Difference Between the Three Jest Cleanup APIs?

Start by separating mock state into three layers:

  1. Usage data: calls, arguments, instances, contexts, and results recorded while the mock was invoked.
  2. Fake behavior: a default or one-time implementation, return value, resolved value, or rejected value configured on the mock.
  3. Original behavior: the real method or property that existed before jest.spyOn or jest.replaceProperty installed a controlled replacement.

clearAllMocks removes the first layer. resetAllMocks removes the first layer and resets the second. restoreAllMocks returns the third layer where Jest knows the original and supports automatic restoration. The APIs are not three aliases and are not simply "small, medium, large" cleanup. Restoration has a different prerequisite: an original value must have been captured.

That prerequisite explains why a standalone jest.fn() cannot be restored to some automatic real implementation. It was created as a mock. There is no previous method behind it. A spy is different because jest.spyOn(object, 'method') wraps an existing property and records enough information to put it back.

The decision becomes easier when the test names the state it changes. If a suite defines one reusable fake response and each test only needs independent call counts, clear usage data. If tests change responses and no behavior should cross the boundary, reset. If a test replaces or spies on a real property, restore the original.

This topic concerns in-process Jest functions and spies. A service stub such as WireMock owns request journals, scenario state, and HTTP responses through different lifecycle APIs. See API mocking with WireMock for that separate boundary.

What State Does a Jest Mock Hold?

A Jest mock is both callable behavior and a record of how it was used. The .mock property exposes arrays and metadata that support assertions:

  • mock.calls contains the argument list for each invocation.
  • mock.results records whether each invocation returned, threw, or remains incomplete, together with its value.
  • mock.instances tracks objects created with the mock as a constructor.
  • mock.contexts tracks the this value for calls.
  • mock.lastCall provides the latest argument list.

Configured behavior lives alongside that history. A mock may use mockImplementation, mockReturnValue, mockResolvedValue, or their one-time variants. Clearing call history should not automatically answer whether those behaviors remain. That is the key distinction between clear and reset.

JavaScript
const loadPlan = jest.fn().mockResolvedValue({
  name: 'pro',
  seats: 5,
});

test('records usage and returns configured data', async () => {
  await expect(loadPlan('account-7')).resolves.toEqual({
    name: 'pro',
    seats: 5,
  });

  expect(loadPlan).toHaveBeenCalledTimes(1);
  expect(loadPlan).toHaveBeenCalledWith('account-7');
  expect(loadPlan.mock.results[0].type).toBe('return');
});

After mockClear, loadPlan.mock.calls and the related usage data are fresh, but calling loadPlan still returns the configured promise. After mockReset, that fake behavior is reset too, so a bare call no longer returns the planned object unless the test configures it again.

Do not store references to the old .mock object and expect them to remain current across clear or reset operations. The Mock Function API warns that mock cleanup replaces the .mock property. Assertions should read loadPlan.mock from the mock after cleanup rather than retaining an earlier alias.

Shared test utilities often hide mock setup behind builders or fixtures. That can be useful, but ownership must stay clear. JavaScript test utility library architecture covers how to keep setup APIs from becoming invisible state. JavaScript closures for fixture and factory design offers another way to create owned state without module-level mutation.

What Does jest.clearAllMocks Clear?

jest.clearAllMocks() applies mock clearing to every Jest mock currently in scope for the environment. Current Jest documentation says it clears calls, instances, contexts, and results. It is equivalent to calling .mockClear() on each mocked function.

Use it when tests share a deliberately configured default behavior but must not share evidence about calls. A file may define an API double that returns a standard account and let individual tests override behavior only when needed. Clearing before each test makes toHaveBeenCalledTimes and toHaveBeenCalledWith local to the current case without rebuilding the default fake.

JavaScript
const analytics = {
  send: jest.fn().mockResolvedValue({ accepted: true }),
};

beforeEach(() => {
  jest.clearAllMocks();
});

test('sends the checkout event once', async () => {
  await checkout(analytics);
  expect(analytics.send).toHaveBeenCalledTimes(1);
});

test('still has the shared fake implementation', async () => {
  await expect(analytics.send({ type: 'page_view' })).resolves.toEqual({
    accepted: true,
  });
  expect(analytics.send).toHaveBeenCalledTimes(1);
});

The second test begins with zero recorded calls, but the configured resolved value remains. That is useful only when sharing the fake behavior is intentional. If a previous test changes the implementation with mockImplementation and cleanup only clears calls, the changed behavior can leak into the next test.

Call-history leakage commonly creates order-dependent assertions: a test expects one call but receives two because a previous test invoked the same mock. clearAllMocks fixes that history boundary. It does not fix mutable fixture objects, module caches, environment variables, fake timers, or server state. Immutable JavaScript test data architecture addresses one of those adjacent state sources.

Avoid calling clearAllMocks midway through a test merely to make an assertion easier. Doing so discards evidence that may matter to the behavior. When a test has phases, keep explicit references to the calls that define each phase, create separate mocks, or assert before an intentional clear. Cleanup should establish test boundaries, not hide inconvenient history.

What Does jest.resetAllMocks Reset?

jest.resetAllMocks() applies .mockReset() to every mock. It resets usage state and mock implementations. The next call behaves like a reset mock rather than the fake configured earlier. This is appropriate when each test must define all behavior it relies on.

A reset policy can make tests more explicit:

JavaScript
const gateway = {
  charge: jest.fn(),
};

beforeEach(() => {
  jest.resetAllMocks();
});

test('accepts an approved charge', async () => {
  gateway.charge.mockResolvedValue({ status: 'approved' });

  await expect(pay(gateway, 499)).resolves.toEqual({
    status: 'approved',
  });
});

test('surfaces a declined charge', async () => {
  gateway.charge.mockRejectedValue(new Error('declined'));

  await expect(pay(gateway, 499)).rejects.toThrow('declined');
});

Each test declares the behavior it needs. If the second test forgot to configure a rejection, it would not inherit the first test's approval. That is the isolation benefit.

The tradeoff is that a reset can remove useful defaults and make every test repeat setup unrelated to its purpose. A suite with one stable contract-level fake may be clearer with clearAllMocks plus local overrides that are restored or reset deliberately. A suite where tests frequently rewrite mock behavior may prefer reset as the safer baseline.

Resetting a spy does not restore the real method. The property remains mocked, but its mock behavior has been reset. This is a common source of confusion: reset concerns mock state, while restore concerns the original property.

resetAllMocks also differs from jest.resetModules(). The latter resets the module registry so future imports can create new module instances. It is useful for cached module-level state or import-time configuration. It is not a stronger mock reset. If the failure is an ESM or CommonJS loading boundary, review debugging ESM and CommonJS conflicts in TypeScript tests rather than using module reset without a diagnosed reason.

What Does jest.restoreAllMocks Restore?

jest.restoreAllMocks() restores original values for mocks created through supported spying and property replacement APIs. Current Jest documentation describes it as applying .mockRestore() to spies and .restore() to replaced properties. Other mocks require their own cleanup because Jest has no captured original to install.

Consider a real analytics object:

JavaScript
const analytics = {
  track(event) {
    return { sent: true, event };
  },
};

afterEach(() => {
  jest.restoreAllMocks();
});

test('records tracking without sending the real event', () => {
  const track = jest
    .spyOn(analytics, 'track')
    .mockReturnValue({ sent: false, event: 'checkout' });

  expect(analytics.track('checkout')).toEqual({
    sent: false,
    event: 'checkout',
  });
  expect(track).toHaveBeenCalledWith('checkout');
});

test('receives the original implementation again', () => {
  expect(analytics.track('page_view')).toEqual({
    sent: true,
    event: 'page_view',
  });
});

The restoration after the first test puts the original track method back. Without restoration, the second test could see the fake return value and fail far from the test that replaced it.

jest.spyOn calls through to the original method by default. That means creating a spy can trigger a real side effect unless the test immediately provides a fake implementation. The repository mock challenge calls out this behavior because it differs from libraries where spying automatically stubs. For network calls, file writes, or billing operations, establish the fake before invoking the method.

Getter, setter, and property replacement cases depend on JavaScript property semantics. JavaScript property descriptors for test doubles explains why some properties can be replaced and restored while others require a different design.

A bare jest.fn() has no original method. restoreAllMocks cannot infer whether it should become a real API, an imported function, or another fake. Keep dependency injection explicit, reset the mock, or rebuild the owning object in setup.

Which Cleanup API Should You Use?

The following table maps the state model to a practical choice. The "bare jest.fn" column means whether the operation has a useful effect on a standalone mock, not whether the function accepts it as part of an all-mocks operation.

APIUsage data clearedFake behavior resetOriginal restoredUseful for bare jest.fnTypical purposeMain surprise
jest.clearAllMocks()YesNoNoYesFresh call assertions with shared defaultsOverrides can survive
jest.resetAllMocks()YesYesNoYesEvery test configures its own behaviorReset spies remain mocks
jest.restoreAllMocks()For restored supported mocksReplaced behavior removed by restorationYes, for supported spies and replaced propertiesNo original to restoreReturn real properties after testsBare mocks are not made real
mockFn.mockClear()One mock onlyNoNoYesLocal call-history boundaryOther mocks are unchanged
mockFn.mockReset()One mock onlyYesNoYesLocal behavior boundaryDefaults disappear
spy.mockRestore()Spy state is discarded with restorationSpy behavior removedYesNot applicableLocal original restorationOnly makes sense with an original

Choose the narrowest operation that enforces the intended boundary. A global reset can hide ownership by changing every mock in the environment when only one spy needs restoration. Conversely, relying on engineers to remember ten local clears may be less reliable than a file-level or project-level policy.

One-time implementations need the same analysis. A mock configured with mockImplementationOnce or mockResolvedValueOnce holds a queue of planned behaviors. If a test does not consume the full queue and cleanup only clears calls, later code can receive a leftover response. Reset removes that queued behavior; clear does not. Tests should consume only the behavior they arrange and choose reset when one-time queues must never cross a boundary.

Call order is another form of evidence, not behavior. Clearing removes the record needed for order assertions but does not undo effects that calls already caused. If a mock implementation mutates a fixture, writes a file, or changes an in-memory service, mock cleanup cannot reverse that side effect. Give the mutable resource its own teardown or replace the implementation with a side-effect-free fake.

Module mocks add setup timing to the decision. A factory installed by jest.mock can define functions that are later cleared or reset, but resetting those functions does not reload the real module. Likewise, restoring a spy does not clear every other export's module-level state. Keep module-registry isolation, function-mock cleanup, and external-resource teardown as separate controls.

Do not enable all three configuration flags by reflex. Clear and reset overlap on usage state, while restore has a different target. A wide policy can make setup order harder to understand. Start from the state tests actually change, then select the policy that leaves each test with a predictable starting point.

Mocking browser APIs has another installation and ownership boundary. See mocking browser APIs before application startup for the Playwright-specific case. Network replay through Playwright HAR also uses different cleanup mechanics.

Follow a Numbered Mock-Cleanup Decision Workflow

Use this workflow when creating a suite policy or diagnosing an order-dependent failure.

  1. Identify the mock type. Is it a standalone jest.fn, a module mock, a jest.spyOn result, or a property installed with jest.replaceProperty?
  2. List the state each test changes. Record whether tests invoke the mock, set one-time results, replace the default implementation, or cover a real property.
  3. Decide whether fake behavior should survive. If a shared default is intentional, clear usage. If every test must configure behavior, reset.
  4. Decide whether a real property must return. If a spy or replaced property should become real after the test, restore it.
  5. Select local, hook, or config cleanup. Use one-mock methods for narrow ownership, hooks for a file policy, and Jest config for a suite-wide rule.
  6. Place setup after the chosen cleanup point. If automatic or beforeEach reset removes implementations, configure required behavior after it.
  7. Run tests individually and in reversed order. A passing isolated test and failing suite indicates state leakage or hidden ordering.
  8. Verify real side effects stay blocked. A restored spy should not cause a later unit test to call a real network, file, clock, or billing dependency unexpectedly.
  9. Inspect failure evidence before cleanup. Cleanup must not run so early that call history needed for assertions or diagnostics disappears.
  10. Document the policy in configuration or setup code. Tests should not rely on a cleanup convention that is visible only in team memory.

This workflow fits test-double design generally, but it does not turn all dependencies into candidates for mocking. BDD versus TDD and the repository's unit-testing material help decide where a focused double supports the behavior under test.

Build a Stateful Example from the Repo Challenge

The javascript-testing-jest-mocks-spies-quiz seed separates jest.fn, jest.spyOn, call assertions, mock results, one-time implementations, and the three cleanup levels. A useful article example should show state crossing a test boundary, not only list method definitions.

The following file uses a stable bare mock and a real clock object. Call history should be fresh for both. The bare mock keeps its default behavior, while the clock spy returns to its original method.

JavaScript
const notifier = jest.fn().mockResolvedValue({ queued: true });

const clock = {
  now() {
    return Date.now();
  },
};

beforeEach(() => {
  jest.clearAllMocks();
});

afterEach(() => {
  jest.restoreAllMocks();
});

test('queues one notification with a controlled timestamp', async () => {
  jest.spyOn(clock, 'now').mockReturnValue(1_800_000_000_000);

  await sendReminder({ notifier, clock });

  expect(notifier).toHaveBeenCalledTimes(1);
  expect(notifier).toHaveBeenCalledWith(
    expect.objectContaining({ sentAt: 1_800_000_000_000 }),
  );
});

test('starts with clean calls and the real clock method', async () => {
  expect(notifier).not.toHaveBeenCalled();
  expect(clock.now()).not.toBe(1_800_000_000_000);

  await expect(notifier({ type: 'check' })).resolves.toEqual({
    queued: true,
  });
});

clearAllMocks gives the second test zero notifier calls while preserving its default resolved value. restoreAllMocks reinstates clock.now. If the suite used resetAllMocks instead, the notifier's default implementation would be reset and the second test would need to configure it again.

To expose the distinction, temporarily remove the restore hook. The second test should reveal the leaked timestamp. Then replace clear with reset and observe that the notifier no longer returns { queued: true }. These negative controls make the cleanup contract visible without inventing a production failure.

The example also avoids reaching into notifier.mock.calls.length when a purpose-built matcher communicates the requirement. Direct call-array inspection is useful for unusual order or argument analysis, but toHaveBeenCalledTimes and toHaveBeenCalledWith produce clearer intent for common contracts.

How Do the Jest Config Options Change the Suite?

Jest configuration exposes clearMocks, resetMocks, and restoreMocks booleans. The current reference describes each as automatically applying its related cleanup before every test. This removes repetitive hooks and establishes a project policy.

clearMocks: true is appropriate when default fake behavior may remain but usage evidence must be fresh. resetMocks: true is appropriate when no test should inherit mock behavior. restoreMocks: true is appropriate when spies and replaced properties should return to their originals automatically.

JavaScript
/** @type {import('jest').Config} */
const config = {
  clearMocks: true,
  restoreMocks: true,
};

module.exports = config;

That sample does not prescribe a universal combination. A project using reset may not need clear because reset already clears usage state. A project with many spies may need restoration even if bare mock behavior is reset separately. Read the current config documentation for the exact version in use.

Configuration also changes where setup belongs. If cleanup occurs before each test, a mock configured once at module evaluation may be cleared or reset before the first case depending on the policy. Put required behavior in beforeEach, a factory, or the test itself when reset is enabled.

Migration to a config policy should include a failure inventory. Run the suite with the proposed option, group failures by missing default behavior, leaked spy, or hidden order dependency, and repair ownership instead of adding a blanket setup that recreates every old leak. A reset policy that forces each test to declare behavior can be valuable, but repeated setup may indicate that a small typed factory would communicate the default more clearly.

Config options also apply beyond the file that motivated the change. A project with unit, integration, and contract tests may not want one mock policy for every project. Jest supports project configuration, so teams can place the cleanup rule beside the suite whose state model it matches. The rule should be discoverable from the command that runs the tests and from the setup file that arranges required defaults.

When a policy changes, run tests in band and with their normal worker settings. Worker isolation can hide file-to-file state while leaving test-to-test leaks inside one file. Conversely, a failure that appears only across workers may come from a real external resource, not Jest mock state. The cleanup API should not be blamed for state it does not own.

Avoid letting global policy obscure special cases. A test that intentionally preserves state across steps should use a single test with explicit phases, not depend on behavior leaking between separate tests. A suite that needs different policies by project can use separate Jest configurations rather than conditional cleanup hidden inside helpers.

Frequently Asked Questions About Jest Mock Cleanup

Does jest.clearAllMocks remove mock implementations?

No. It clears recorded usage data such as calls, instances, contexts, and results. Configured return values and implementations remain. This makes clear useful for fresh call assertions when a shared default fake behavior is intentional.

Does jest.resetAllMocks restore spied methods?

No. It resets mock usage and behavior, but a spied property remains mocked. Use jest.restoreAllMocks() or the individual spy's mockRestore() when the real method must be put back.

Does jest.restoreAllMocks work on jest.fn?

A standalone jest.fn() has no captured original implementation. Restoration applies to supported spies and replaced properties. Clear or reset a bare function, or reconstruct the owning dependency explicitly when a different implementation is required.

Should cleanup run in beforeEach or afterEach?

Both can establish isolation. beforeEach guarantees incoming state before setup, while afterEach places restoration with teardown. Automatic config options can centralize the policy. Keep the choice consistent and ensure cleanup does not remove evidence before assertions or failure reporting.

Can I enable cleanup in Jest config?

Yes. Use clearMocks, resetMocks, and restoreMocks according to the state boundary the suite needs. Avoid enabling overlapping policies without understanding setup order and implementation removal. Recheck the configuration reference for the Jest version used by the project.

Is jest.resetModules the same as jest.resetAllMocks?

No. resetModules clears the module registry for fresh imports. resetAllMocks resets mock function usage and behavior. Diagnose whether the shared state belongs to a module instance or a mock before choosing either operation.

Conclusion: Reset Only the State the Test Changed

The Jest clear reset restore mocks decision follows the three-layer model. Clear when only call evidence must be fresh. Reset when fake behavior must not survive. Restore when a supported spy or replaced property must return to its original value. A standalone mock can be cleared or reset, but it has no automatic original to restore.

Choose the narrowest policy that creates a predictable starting point, verify it by reversing test order, and keep real side effects under control. That turns mock cleanup from a memorized trio into an ownership rule. For wider network-double scenarios, Playwright network mocking interview scenarios show where request routing and browser context lifecycles replace Jest's in-process mock state.

// LIVE COURSE / THE TESTING ACADEMY

Playwright Automation Mastery

Go beyond Selenium. Master Playwright with JS/TS in 90 days.

From the instructor behind this guide.

Playwright jobs are growing 8x faster than Selenium. 90 days / 75+ live hrs / Tue-Thu-Sat 7 AM IST.

Code PROMODE / 10% offJoin the batch

The Testing Academy editorial desk

Practical QA guidance built around test evidence, production tradeoffs, and interview-ready explanations.

Published July 25, 2026 / Reviewed July 25, 2026

PRIMARY REFERENCES

Verify the details at the source

QABattle guides are practical explanations. Product behavior, standards, and APIs can change, so use these primary references for the canonical details.

  1. 01
    Official jestjs.io reference

    jestjs.io

    Primary documentation selected and verified for the claims in this guide.

  2. 02
    Official jestjs.io reference

    jestjs.io

    Primary documentation selected and verified for the claims in this guide.

  3. 03
    Official jestjs.io reference

    jestjs.io

    Primary documentation selected and verified for the claims in this guide.

  4. 04
    WebDriver standard

    W3C

    The browser automation protocol specification used by major automation stacks.

FAQ / QUICK ANSWERS

Questions testers ask

Does jest.clearAllMocks remove mock implementations?

No. clearAllMocks clears usage data such as calls, instances, contexts, and results for every mock, but configured implementations and return values remain available. Use it when each test needs fresh call history while a shared default fake behavior is intentionally established for the file or suite.

Does jest.resetAllMocks restore spied methods?

No. resetAllMocks resets mock state and fake implementations, but it does not put an original spied method back in place. A reset spy remains a mock with reset behavior. Use restoreAllMocks, or the individual spy's mockRestore method, when the real implementation must be reinstated.

Does jest.restoreAllMocks work on jest.fn?

A standalone jest.fn has no original implementation for Jest to reinstall. Current Jest documentation limits automatic restoration to supported spies and replaced properties. You can clear or reset a bare mock, or assign the original dependency through your own setup when the test architecture requires a different implementation.

Should mock cleanup run in beforeEach or afterEach?

Either can establish isolation, but the choice should be consistent and visible. beforeEach guarantees the incoming state is clean before setup. afterEach places restoration beside teardown and runs after assertions. Automatic config options can remove repetition. Cleanup must not erase evidence before a failing test is reported.

Can I enable clearMocks, resetMocks, or restoreMocks in Jest config?

Yes. Jest provides boolean configuration options that apply the related cleanup before each test. Select the narrowest policy that matches suite ownership. Enabling a wider reset can remove default mock behavior unexpectedly, while restoration is appropriate when tests create spies or replace properties that must return to originals.

Is jest.resetModules the same as jest.resetAllMocks?

No. resetAllMocks changes Jest mock function state. resetModules clears the module registry so later imports can receive fresh module instances. They address different sources of shared state. Use module isolation only when cached module state is the problem, not as a substitute for choosing the correct mock cleanup operation.