How to Mock Apollo Client in React
Testing React components that integrate with GraphQL requires a
reliable way to simulate network requests without hitting a live server.
This article explains how to mock Apollo Client in React using the
official MockedProvider utility. You will learn how to
define mock requests, inject them into your components during testing,
and handle asynchronous loading and success states.
Using MockedProvider
The @apollo/client/testing package provides
MockedProvider, a component that mocks the behavior of
ApolloProvider. Instead of sending network requests to a
GraphQL endpoint, MockedProvider intercepts queries and
mutations and returns predefined mock data that you specify.
1. Create the Mock Data
To mock a query, you need to define an array of mock objects. Each
mock object contains a request property (specifying the
query and variables to match) and a result property
(specifying the data to return).
import { gql } from '@apollo/client';
export const GET_USER_QUERY = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
export const mocks = [
{
request: {
query: GET_USER_QUERY,
variables: { id: '1' },
},
result: {
data: {
user: {
id: '1',
name: 'John Doe',
email: 'john@example.com',
},
},
},
},
];2. Write the Component Test
When rendering your component in a test environment (such as React
Testing Library), wrap the component with MockedProvider
and pass the mock array to the mocks prop.
import React from 'react';
import { render, screen } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { UserComponent } from './UserComponent';
import { GET_USER_QUERY, mocks } from './mocks';
test('renders user data successfully', async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<UserComponent id="1" />
</MockedProvider>
);
// Verify the loading state first
expect(screen.getByText(/loading.../i)).toBeInTheDocument();
// Wait for the mock data to resolve and render
const nameElement = await screen.findByText('John Doe');
expect(nameElement).toBeInTheDocument();
expect(screen.getByText('john@example.com')).toBeInTheDocument();
});3. Key Considerations
- Exact Matching: Apollo Client matches mocks based on exact query and variable similarity. If your component sends variables that do not exactly match those defined in your mock, the query will fail with an error stating that no mock was found.
- addTypename: By default, Apollo Client
automatically adds
__typenamefields to queries. If your mock data does not include__typenamefields, setaddTypename={false}on theMockedProviderto prevent matching failures. - Asynchronous Resolution: Because GraphQL requests
are asynchronous, the component will always render the loading state
first. Use asynchronous queries like
findByfrom React Testing Library to wait for the mocked response to render on the screen.
4. Mocking Mutations
Mocking mutations follows the exact same pattern. You specify the mutation query, the input variables, and the expected result inside the mock array.
const UPDATE_USER_MUTATION = gql`
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
}
}
`;
const mutationMock = {
request: {
query: UPDATE_USER_MUTATION,
variables: { id: '1', name: 'Jane Doe' },
},
result: {
data: {
updateUser: {
id: '1',
name: 'Jane Doe',
__typename: 'User',
},
},
},
};