How to have different mock responses for multiple tests using Jest and React


I am quite confused with mocking in Jest. I just want to mock different expected behaviors per test

Although not always possible, a more straightforward approach than mocking a module with Jest is to change the React component to receive the dependency as a prop. This approach allows us to pass a different mock function or mock value per test, without having to worry about the quirks of mocking modules.

So we don't have to change code that uses the component we're testing, we can use default parameters.

Here's how this approach looks like:

import { fetchTodosFromAPI } from './api-client';

function TodosList({ fetchTodos = fetchTodosFromAPI }) {
  // gets todos from fetchTodos() and renders result
}
// tests using react-testing-library
test('shows message when to-do list is empty', () => {
  const fetchEmptyListOfTodos = jest.fn().mockResolvedValue([]);
  render(<TodosList fetchTodos={fetchEmptyListOfTodos} />);
  // asserts renders message for empty to-dos list
});

test('shows list with one to-do', () => {
  const fetchListWithOneTodo = jest
    .fn()
    .mockResolvedValue([{ id: 1, title: 'Study testing' }]);
  render(<TodosList fetchTodos={fetchListWithOneTodo} />);
  // assert renders single todo
});

test('shows error message when there is a network failure', () => {
  const rejectWithNetworkFailure = jest
    .fn()
    .mockRejectedValue(new Error('Network failure'));
  render(<TodosList fetchTodos={rejectWithNetworkFailure} />);
  // asserts renders error message
});

Put it into practice

  1. Change the component to receive the dependency as a prop.
  2. Use default parameters to pass the production dependency to the component.
  3. Go to your tests, and instead of mocking the dependency module, give a mock function to the component through the new prop.

Although I only referenced React components, this approach also works well for everyday javascript function.