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.
In this guide11 sections
- 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?
- What Does jest.restoreAllMocks Restore?
- Which Cleanup API Should You Use?
- Follow a Numbered Mock-Cleanup Decision Workflow
- Build a Stateful Example from the Repo Challenge
- How Do the Jest Config Options Change the Suite?
- Frequently Asked Questions About Jest Mock Cleanup
- Does jest.clearAllMocks remove mock implementations?
- Does jest.resetAllMocks restore spied methods?
- Does jest.restoreAllMocks work on jest.fn?
- Should cleanup run in beforeEach or afterEach?
- Can I enable cleanup in Jest config?
- Is jest.resetModules the same as jest.resetAllMocks?
- 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:
- Usage data: calls, arguments, instances, contexts, and results recorded while the mock was invoked.
- Fake behavior: a default or one-time implementation, return value, resolved value, or rejected value configured on the mock.
- Original behavior: the real method or property that existed before
jest.spyOnorjest.replacePropertyinstalled 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.callscontains the argument list for each invocation.mock.resultsrecords whether each invocation returned, threw, or remains incomplete, together with its value.mock.instancestracks objects created with the mock as a constructor.mock.contextstracks thethisvalue for calls.mock.lastCallprovides 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.
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.
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:
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:
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.
| API | Usage data cleared | Fake behavior reset | Original restored | Useful for bare jest.fn | Typical purpose | Main surprise |
|---|---|---|---|---|---|---|
jest.clearAllMocks() | Yes | No | No | Yes | Fresh call assertions with shared defaults | Overrides can survive |
jest.resetAllMocks() | Yes | Yes | No | Yes | Every test configures its own behavior | Reset spies remain mocks |
jest.restoreAllMocks() | For restored supported mocks | Replaced behavior removed by restoration | Yes, for supported spies and replaced properties | No original to restore | Return real properties after tests | Bare mocks are not made real |
mockFn.mockClear() | One mock only | No | No | Yes | Local call-history boundary | Other mocks are unchanged |
mockFn.mockReset() | One mock only | Yes | No | Yes | Local behavior boundary | Defaults disappear |
spy.mockRestore() | Spy state is discarded with restoration | Spy behavior removed | Yes | Not applicable | Local original restoration | Only 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.
- Identify the mock type. Is it a standalone
jest.fn, a module mock, ajest.spyOnresult, or a property installed withjest.replaceProperty? - 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.
- Decide whether fake behavior should survive. If a shared default is intentional, clear usage. If every test must configure behavior, reset.
- Decide whether a real property must return. If a spy or replaced property should become real after the test, restore it.
- 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.
- Place setup after the chosen cleanup point. If automatic or
beforeEachreset removes implementations, configure required behavior after it. - Run tests individually and in reversed order. A passing isolated test and failing suite indicates state leakage or hidden ordering.
- 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.
- Inspect failure evidence before cleanup. Cleanup must not run so early that call history needed for assertions or diagnostics disappears.
- 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.
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.
/** @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.
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.
- 01Official jestjs.io reference
jestjs.io
Primary documentation selected and verified for the claims in this guide.
- 02Official jestjs.io reference
jestjs.io
Primary documentation selected and verified for the claims in this guide.
- 03Official jestjs.io reference
jestjs.io
Primary documentation selected and verified for the claims in this guide.
- 04
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.
RELATED GUIDES
Continue the learning route
GUIDE 01
JavaScript Property Descriptors for Test Doubles
A practical guide to JavaScript property descriptors testing, covering design, implementation, debugging, scale, measurable release gates, and senior interview scenarios.
GUIDE 02
API Mocking with WireMock: Stubs, Tests, and Examples
API mocking with WireMock guide for QA teams covering stubs, request matching, delays, faults, recording, contracts, CI, and mistakes.
GUIDE 03
Mock Browser APIs Before App Startup with Playwright addInitScript
Mock browser APIs before app startup with Playwright addInitScript, stateful event doubles, read-only overrides, call recording, and focused UI assertions.
GUIDE 04
JavaScript Test Utility Library Architecture
Master JavaScript test utility architecture with practical examples, architecture decisions, failure analysis, CI guidance, metrics, and scenario-led interview answers.
GUIDE 05
Immutable Test Data Architecture in JavaScript
JavaScript immutable test data architecture: practical design, implementation, debugging, CI, metrics, and interview guidance for QA, SDET, and automation engineers.