π§ͺ React Mocking APIs in Tests β Simulate Network Calls for Reliable Testing (2025 Guide)
π§² Introduction β Why Mock APIs in React Tests?
React applications often rely on APIs to fetch or submit data. When testing such components, calling real APIs is slow, flaky, and unreliable.
Mocking APIs allows you to:
- β‘ Speed up tests
- π« Avoid actual network requests
- π§ͺ Simulate API responses (success, error, delay)
- β Test components in isolation
π― In this guide, youβll learn:
- How to mock APIs using
jest.fn()
,fetch
, andaxios
- Mock with
MSW
(Mock Service Worker) - Handle different HTTP methods and edge cases
- Best practices for mocking external data in React Testing Library (RTL)
π§ 1. Mocking fetch
with Jest
β Component Example:
useEffect(() => {
fetch('/api/data')
.then(res => res.json())
.then(setData);
}, []);
β Test Example:
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve(['apple', 'banana']),
})
);
test('renders fetched data', async () => {
render(<Component />);
expect(await screen.findByText('apple')).toBeInTheDocument();
});
π Use findByText()
or waitFor()
for async assertions
β
Works for global fetch
in most apps
π¦ 2. Mocking Axios with Jest
β Component:
import axios from 'axios';
useEffect(() => {
axios.get('/api/items').then((res) => setItems(res.data));
}, []);
β Test:
jest.mock('axios');
test('renders axios data', async () => {
axios.get.mockResolvedValue({ data: ['apple', 'banana'] });
render(<Component />);
expect(await screen.findByText('banana')).toBeInTheDocument();
});
β
Mocks the entire axios module
π Use mockRejectedValue()
for simulating errors
π§ͺ 3. Using MSW β Mock Service Worker (Recommended for Integration Tests)
β Install:
npm install msw --save-dev
β Create a Handler:
// handlers.js
import { rest } from 'msw';
export const handlers = [
rest.get('/api/items', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(['apple', 'banana']));
}),
];
β Setup Server in Test:
// setupTests.js
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
const server = setupServer(...handlers);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
π Works at the network level β no need to mock fetch
or axios
directly
β
Ideal for full test coverage of REST APIs
π 4. Simulating Error States
β Jest Example:
fetch.mockImplementationOnce(() =>
Promise.reject(new Error('API error'))
);
β MSW Example:
rest.get('/api/items', (req, res, ctx) => {
return res(ctx.status(500));
});
π Test error boundaries, fallback UIs, and retry logic
π Best Practices
β
Use jest.fn()
for simple unit tests
β
Use msw
for integration/end-to-end behavior
β
Always reset or restore mocks to avoid test pollution
β
Mock both success and failure cases
β
Assert against user-visible output, not internal state
π Summary β Recap & Next Steps
Mocking APIs is critical for writing fast, reliable, and isolated React tests. Whether you’re unit testing with jest.fn()
or doing full integration with MSW, mocking helps control every aspect of your componentβs data interaction.
π Key Takeaways:
- Use
jest.fn()
ormockResolvedValue()
to fake APIs - Use
MSW
for network-level, behavior-first mocking - Test both loading, success, and failure states
- Always restore/reset mocks between tests
- Focus on testing user-facing behavior
βοΈ Real-World Relevance:
Used in apps like GitHub, Vercel, and Shopify to reliably test everything from form submissions to REST APIsβwithout depending on live servers.
β FAQ Section
β Should I use jest.fn()
or MSW?
β
Use jest.fn()
for unit tests. Use MSW
for integration or behavior-driven tests.
β How do I test API failures?
β
Use mockRejectedValue()
(Jest) or return ctx.status(500)
(MSW) to simulate errors.
β Can I mock GraphQL APIs with MSW?
β
Yes! MSW supports GraphQL with graphql.query()
and graphql.mutation()
handlers.
β Should I test loading states too?
β
Absolutely. Mock slow responses or use manual loading triggers and assert loading spinners or skeletons.
β Do I need to reset mocks?
β
Yes. Always use afterEach(() => jest.resetAllMocks())
or reset handlers in MSW to avoid test cross-contamination.
Share Now :