Mocking API Calls in Tests
In this page:
const mockFn = jest.fn();
mockFn.mockResolvedValue(fakeData);
global.fetch = jest.fn(() =>
Promise.resolve({ json: () => Promise.resolve(fakeData) })
);
afterEach(() => jest.resetAllMocks());
Why Mock API Calls in Tests
Making real network requests in tests is slow, depends on an external service actually being available, and can produce different results each run.
Mocking replaces the real request with a fake, predictable response, making tests fast, reliable, and independent of any real backend.
Example: Why Mock API Calls in Tests
// Run in your local React project (npm install required)
test('fetches and displays user', async () => {
global.fetch = jest.fn(() =>
Promise.resolve({ json: () => Promise.resolve({ name: 'Asha' }) })
);
render(<UserProfile userId={1} />);
expect(await screen.findByText('Asha')).toBeInTheDocument();
});
Creating a Mock Function with jest.fn()
jest.fn() creates a special mock function that records how it was called (arguments, call count) and lets you control what it returns, without running any real logic. This is useful for mocking not just fetch, but any function a component depends on.
Example: Creating a Mock Function with jest.fn()
// Run in your local React project (npm install required)
const mockOnSave = jest.fn();
test('calls onSave when button clicked', async () => {
const user = userEvent.setup();
render(<SaveButton onSave={mockOnSave} />);
await user.click(screen.getByText('Save'));
expect(mockOnSave).toHaveBeenCalledTimes(1);
});
Resetting Mocks Between Tests
Mock functions and mocked globals (like fetch) can retain state (like call counts) across tests if not reset, causing one test's setup to accidentally affect another.
Calling jest.clearAllMocks() or restoring the original implementation in afterEach keeps each test properly isolated.
Example: Resetting Mocks Between Tests
// Run in your local React project (npm install required)
afterEach(() => {
jest.clearAllMocks();
delete global.fetch;
});
test('example test', () => {
global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve({}) }));
// ... test body
});
- Making real network requests in tests, which are slow, flaky, and depend on an external service being up.
- Forgetting to reset or restore mocks between tests, letting one test's mock leak into another.
- Mocking fetch's response shape incorrectly, not matching what the real API actually returns.
- Mocking replaces a real API call with a fake, predictable one for testing purposes.
- jest.fn() creates a mock function you can control and inspect within a test.
- Global fetch can be mocked directly, or a library like msw can intercept requests more realistically.
- Resetting mocks between tests (afterEach) avoids one test's setup leaking into another.
Requires npm install (Jest/Vitest) — mocking runs in the Node test environment, not this browser sandbox.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: