0
0
ReactHow-ToBeginner · 4 min read

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 beforeEach to reset mocks.
  • Forgetting to mock fetch or the API module leads to real network calls, slowing tests and causing flakiness.
  • Not awaiting async UI updates can make tests fail; always use waitFor or findBy queries.
  • 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.fetch with jest.fn() for fetch calls.
  • Use mockResolvedValueOnce to simulate async responses.
  • Use React Testing Library's waitFor or findBy to 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.