How to Mock API Call in React Test: Simple Guide
To mock an API call in a React test, use
jest.mock to replace the API module or global.fetch with a mock function. Then, use React Testing Library to render your component and verify behavior without real network requests.Syntax
Use jest.mock('moduleName', () => mockImplementation) to replace an imported API module with a mock. Alternatively, mock global.fetch with jest.fn() to simulate fetch calls.
Then, render your React component with React Testing Library's render() and use waitFor or findBy queries to test async UI updates.
javascript
import { render, screen, waitFor } from '@testing-library/react'; import MyComponent from './MyComponent'; // Mocking fetch example beforeEach(() => { global.fetch = jest.fn(); }); test('mock fetch call', async () => { fetch.mockResolvedValueOnce({ json: async () => ({ data: 'mocked data' }), }); render(<MyComponent />); await waitFor(() => expect(screen.getByText(/mocked data/i)).toBeInTheDocument()); });
Example
This example shows how to mock a fetch API call in a React component test using Jest and React Testing Library. The component fetches data on mount and displays it. The test mocks the fetch call to return fake data and checks if the component renders it.
javascript
import React, { useEffect, useState } from 'react'; import { render, screen, waitFor } from '@testing-library/react'; // Simple component that fetches data function MyComponent() { const [data, setData] = useState(null); useEffect(() => { fetch('/api/data') .then(res => res.json()) .then(json => setData(json.data)); }, []); if (!data) return <div>Loading...</div>; return <div>Data: {data}</div>; } // Test beforeEach(() => { global.fetch = jest.fn(); }); test('renders mocked API data', async () => { fetch.mockResolvedValueOnce({ json: async () => ({ data: 'Hello from mock!' }), }); render(<MyComponent />); expect(screen.getByText(/loading/i)).toBeInTheDocument(); await waitFor(() => expect(screen.getByText(/hello from mock!/i)).toBeInTheDocument()); });
Output
Loading... (initially)
Data: Hello from mock! (after fetch resolves)
Common Pitfalls
- Not resetting mocks between tests can cause unexpected results; use
beforeEachto reset mocks. - Forgetting to mock
fetchor the API module leads to real network calls, slowing tests and causing flakiness. - Not awaiting async UI updates can make tests fail; always use
waitFororfindByqueries. - Mocking only once but calling API multiple times can cause errors; mock each call or use
mockImplementation.
javascript
/* Wrong: No mock reset, causes test interference */ beforeAll(() => { global.fetch = jest.fn(); }); test('first test', () => { fetch.mockResolvedValueOnce({ json: async () => ({ data: 'one' }) }); // ... }); test('second test', () => { fetch.mockResolvedValueOnce({ json: async () => ({ data: 'two' }) }); // This may fail if fetch mock is not reset }); /* Right: Reset mocks before each test */ beforeEach(() => { global.fetch = jest.fn(); });
Quick Reference
Mocking API calls in React tests:
- Use
jest.mock()to mock imported API modules. - Mock
global.fetchwithjest.fn()for fetch calls. - Use
mockResolvedValueOnceto simulate async responses. - Use React Testing Library's
waitFororfindByto handle async UI updates. - Reset mocks between tests with
beforeEach.
Key Takeaways
Mock API calls using jest.mock or by mocking global.fetch with jest.fn().
Always await async UI changes with waitFor or findBy queries in tests.
Reset mocks before each test to avoid interference between tests.
Mock responses with mockResolvedValueOnce to simulate API data.
Use React Testing Library to render components and verify UI after mock calls.