How to Mock GraphQL in React

Mocking GraphQL in React is essential for testing components in isolation, speeding up development, and avoiding dependency on a live backend server. This article covers the two most popular and effective methods for mocking GraphQL in a React application: using Apollo Client’s built-in MockedProvider for component-level testing, and using Mock Service Worker (MSW) for mocking at the network level.

Method 1: Using Apollo Client’s MockedProvider

If your React application uses Apollo Client, the easiest way to mock GraphQL queries and mutations in unit tests is by using MockedProvider. This utility wraps your components and intercepts GraphQL operations, returning specified mock data instead of making actual network requests.

1. Define the Mock Data

To use MockedProvider, you must define an array of mock objects. Each mock object contains a request (the query and variables) and a result (the mock data to return).

import { GET_USER_QUERY } from './UserComponent';

const mocks = [
  {
    request: {
      query: GET_USER_QUERY,
      variables: { id: '123' },
    },
    result: {
      data: {
        user: {
          id: '123',
          name: 'Jane Doe',
          email: 'jane@example.com',
        },
      },
    },
  },
];

2. Wrap the Component in your Test

Pass the mocks array to the MockedProvider wrapper in your test file.

import { render, screen } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { UserComponent } from './UserComponent';

test('renders user data correctly', async () => {
  render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <UserComponent id="123" />
    </MockedProvider>
  );

  // Verification
  expect(screen.getByText(/loading/i)).toBeInTheDocument();
  const nameElement = await screen.findByText('Jane Doe');
  expect(nameElement).toBeInTheDocument();
});

Method 2: Using Mock Service Worker (MSW)

Mock Service Worker (MSW) is a library that intercepts API requests at the network level using a Service Worker in the browser or a request interceptor in Node.js. MSW is ideal for integration and End-to-End (E2E) testing because it works independently of your React code and supports any GraphQL client (Apollo, Relay, or standard fetch).

1. Set Up MSW Handlers

Define the GraphQL queries or mutations you want to intercept.

// src/mocks/handlers.js
import { graphql } from 'msw';

export const handlers = [
  graphql.query('GetUser', (req, res, ctx) => {
    const { id } = req.variables;
    
    return res(
      ctx.data({
        user: {
          id,
          name: 'Jane Doe',
          email: 'jane@example.com',
        },
      })
    );
  }),
];

2. Configure the Mock Server for Testing

Set up the MSW server to run during your test suite.

// src/mocks/server.js
import { setupServer } from 'msw/node';
import { handlers } from './handlers';

export const server = setupServer(...handlers);

3. Integrate with Jest or Vitest

Configure your testing framework to start the MSW server before tests run and clean up afterward.

// src/setupTests.js
import { server } from './mocks/server';

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

With MSW configured, your React components can be tested using standard renders without needing wrapping providers like MockedProvider. The actual network fetch is seamlessly intercepted, allowing you to test the exact production setup of your application.