How to Mock Redux Dispatch in React
This article provides a straightforward guide on how to mock the
Redux useDispatch hook in React applications for unit
testing. You will learn how to mock the react-redux module
using Jest and write assertions to verify that your React components
dispatch the correct actions when triggered.
The Mocking Approach
When unit testing React components that use Redux, you often want to
isolate the component from the actual Redux store. Instead of
configuring a real store, you can mock the useDispatch hook
using Jest. This allows you to spy on the dispatch function and assert
that it was called with the expected action.
Here is a step-by-step implementation.
1. The React Component
Consider a simple button component that dispatches an action to increment a counter:
// CounterButton.js
import React from 'react';
import { useDispatch } from 'react-redux';
export const CounterButton = () => {
const dispatch = useDispatch();
const handleClick = () => {
dispatch({ type: 'INCREMENT' });
};
return <button onClick={handleClick}>Increment</button>;
};2. Writing the Test with Jest
To test this component, mock react-redux using
jest.mock(). You will override useDispatch to
return a mock function (jest.fn()), which you can then
inspect in your test assertions.
// CounterButton.test.js
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { useDispatch } from 'react-redux';
import { CounterButton } from './CounterButton';
// Mock the react-redux library
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useDispatch: jest.fn(),
}));
describe('CounterButton Component', () => {
let mockDispatch;
beforeEach(() => {
// Reset the mock before each test
mockDispatch = jest.fn();
useDispatch.mockReturnValue(mockDispatch);
});
afterEach(() => {
jest.clearAllMocks();
});
it('should dispatch the INCREMENT action when clicked', () => {
render(<CounterButton />);
// Find the button and trigger a click event
const button = screen.getByRole('button', { name: /increment/i });
fireEvent.click(button);
// Assert that dispatch was called with the correct action object
expect(mockDispatch).toHaveBeenCalledTimes(1);
expect(mockDispatch).toHaveBeenCalledWith({ type: 'INCREMENT' });
});
});Key Takeaways
- Mocking the Module: Using
jest.mock('react-redux')lets you intercept the library’s hooks. - Preserving Other Features: The
jest.requireActual('react-redux')helper ensures that other hooks (likeuseSelector) and providers function normally if they are not explicitly mocked. - Isolating Tests: Assigning
useDispatch.mockReturnValue(mockDispatch)insidebeforeEachensures a clean mock instance for every individual test case.