100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Testing

Mock Functions with jest.fn()

Learn how to create, configure, and inspect Jest mock functions to isolate units under test and verify how dependencies are called.

MockingBeginner8 min readJul 10, 2026
Analogies

What Is a Mock Function?

jest.fn() creates a standalone mock function — a fake, callable stand-in that automatically records every call made to it, including the arguments it received, the value it returned, and how many times it fired. You typically pass a jest.fn() in place of a real callback, event handler, or dependency function so your test can both control its behavior and assert on how the code under test interacted with it, without invoking any real logic.

🏏

Cricket analogy: Virat Kohli facing a bowling machine that logs every ball's speed and length is like jest.fn() — the machine records each 'call' (delivery) so you can review the spell afterward.

Creating and Configuring Mock Functions

By default a jest.fn() returns undefined, but you can configure its behavior with mockReturnValue(value) for a fixed synchronous result, mockResolvedValue(value) or mockRejectedValue(error) for Promise-based code, or mockImplementation(fn) when you need custom logic per call, including conditional behavior based on arguments. Chaining the 'Once' variants — mockReturnValueOnce, mockImplementationOnce — lets a mock behave differently on successive invocations, which is essential for testing retry logic or multi-step flows.

🏏

Cricket analogy: Setting a bowling machine to always deliver a yorker on off stump is like mockReturnValue — you configure jest.fn() to return a fixed result every time it's invoked, e.g. a fake API response.

javascript
const add = jest.fn((a, b) => a + b);

add(2, 3);
add(4, 5);

expect(add).toHaveBeenCalledTimes(2);
expect(add).toHaveBeenCalledWith(4, 5);
expect(add.mock.results[0].value).toBe(5);

const fetchUser = jest.fn();
fetchUser.mockReturnValueOnce({ id: 1, name: 'Ada' });
fetchUser.mockImplementationOnce(() => {
  throw new Error('not found');
});

Inspecting Mock Calls

Every jest.fn() exposes a .mock property containing everything Jest recorded: mock.calls is an array where each entry is the argument list for one call, mock.results holds the {type, value} outcome of each call (return, throw, or the resolved value), and mock.instances captures the this context for each invocation. Matchers like toHaveBeenCalledWith, toHaveBeenCalledTimes, and toHaveBeenLastCalledWith are simply convenient wrappers around reading this .mock data, so you rarely need to inspect mock.calls manually except when debugging.

🏏

Cricket analogy: A scorer checking the ball-by-ball commentary to confirm Jasprit Bumrah bowled exactly 4 overs in the powerplay mirrors toHaveBeenCalledTimes — you inspect mock.calls to verify how a function was actually used.

The .mock property on every jest.fn() exposes .calls (array of argument arrays), .results (array of {type, value} objects), and .instances (values of this for each call) — inspect it directly with console.log(fn.mock) when debugging a failing assertion.

Resetting and Restoring Mocks

Test isolation depends on cleaning up mock state between tests: mockClear() erases recorded calls and results but keeps any configured mockImplementation or mockReturnValue in place; mockReset() does everything mockClear() does and additionally removes configured behavior, reverting the mock to a plain jest.fn() that returns undefined; mockRestore() — available only on jest.spyOn() spies — goes further still and reinstalls the original, un-mocked function. Rather than calling these manually in every afterEach, most projects set clearMocks, resetMocks, or restoreMocks to true in jest.config.js so Jest handles cleanup automatically before each test.

🏏

Cricket analogy: Wiping the scoreboard clean before a new net session, versus completely rebuilding the pitch, mirrors mockClear (clears calls) versus mockRestore (returns to the original, unmocked bowler like Mohammed Shami).

mockClear() only wipes recorded calls and results; mockReset() also removes any configured mockImplementation/mockReturnValue; mockRestore() (spies only) additionally re-installs the original, un-mocked function. Using the wrong one is a common source of test bleed between it() blocks.

  • jest.fn() creates a standalone mock function that records every call, its arguments, and its return value.
  • mockReturnValue, mockResolvedValue, and mockImplementation let you control what a mock returns without executing real logic.
  • The .mock property (calls, results, instances) is the raw data source behind matchers like toHaveBeenCalledWith.
  • mockClear() resets call history, mockReset() also clears configured behavior, and mockRestore() (spies only) reinstates the original function.
  • clearMocks / resetMocks / restoreMocks in jest.config can automate cleanup between every test instead of calling them manually.
  • mockReturnValueOnce and mockImplementationOnce let a mock behave differently on successive calls.
  • Mock functions are essential for isolating the unit under test from callbacks, event handlers, and dependency functions.

Practice what you learned

Was this page helpful?

Topics covered

#Testing#JestStudyNotes#TestingQA#MockFunctionsWithJestFn#Mock#Functions#Jest#Function#StudyNotes#SkillVeris