jest.fn() is the foundation of Jest's mocking system. This lesson covers how to create mock functions and configure exactly what they return or do when called.
Creating a Mock Function
jest.fn() with no arguments creates a mock that returns undefined by default when called, but still tracks every call. jest.fn(implementation) creates a mock that runs the given implementation function whenever it's called, which is useful when the fake needs to behave like a real (simplified) function.
Beyond creation, mock functions expose chainable configuration methods like .mockReturnValue() and .mockImplementation() that let you control behavior after the fact, even changing it between calls.
const add = jest.fn((a, b) => a + b);
expect(add(2, 3)).toBe(5);
expect(add).toHaveBeenCalledWith(2, 3);
Passing a real implementation to jest.fn() lets the mock behave like an actual function while still tracking calls.
Configuring Return Values
mockFn.mockReturnValue(42);
mockFn.mockReturnValueOnce(1).mockReturnValueOnce(2);
mockFn.mockImplementation((a, b) => a * b);
mockFn.mockResolvedValue({ ok: true });
mockFn.mockRejectedValue(new Error('failed'));
.mockReturnValue(x) makes every call return x.
.mockReturnValueOnce(x) queues a value for just the next call; chain multiple for a sequence.
.mockImplementation(fn) replaces the function's behavior entirely, including logic and side effects.
.mockResolvedValue()/.mockRejectedValue() are shortcuts for functions that return promises.
jest.fn() Cheat Sheet
Every common way to create and configure a mock function.
Method
Effect
jest.fn()
Creates a mock returning undefined
jest.fn(impl)
Creates a mock running a custom implementation
.mockReturnValue(x)
Always returns x
.mockReturnValueOnce(x)
Returns x for just the next call
.mockImplementation(fn)
Runs fn as the mock's logic
.mockImplementationOnce(fn)
Runs fn for just the next call
.mockResolvedValue(x)
Returns a promise resolved with x
.mockRejectedValue(err)
Returns a promise rejected with err
Returning a Different Value on Each Call
.mockReturnValueOnce() (and .mockImplementationOnce()) can be chained multiple times to queue up a sequence of different results, one per call, falling back to any default set with .mockReturnValue() once the queue is exhausted.
const nextId = jest.fn()
.mockReturnValueOnce(1)
.mockReturnValueOnce(2)
.mockReturnValue(3); // used for the 3rd call and beyond
expect(nextId()).toBe(1);
expect(nextId()).toBe(2);
expect(nextId()).toBe(3);
expect(nextId()).toBe(3);
Mocking Async Functions with mockResolvedValue
.mockResolvedValue(x) is shorthand for .mockImplementation(() => Promise.resolve(x)), and .mockRejectedValue(err) is shorthand for a rejected promise. Both make testing async dependencies dramatically simpler.
Use .mockReturnValueOnce() chains to simulate a flaky dependency that fails once and then succeeds — it's a realistic and easy way to test retry logic.
You now know how to configure jest.fn() thoroughly. Next, learn about jest.spyOn() and how spies differ from plain mock functions.