How to Mock Redux Toolkit in React
Testing React components that use Redux Toolkit (RTK) requires a strategy to isolate components from the actual global state. This article explains how to mock Redux Toolkit in React using Jest and React Testing Library, covering both the recommended approach of wrapping components in a test provider and the alternative method of mocking individual React-Redux hooks.
Method 1: Wrapping Components with a Real Store (Recommended)
The most reliable way to test components using Redux Toolkit is to
wrap them in a <Provider> with a real Redux store
configured specifically for testing. This avoids fragile mocks and
ensures your tests behave exactly like your application.
First, create a reusable render helper that configures a fresh store for each test:
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './userSlice'; // Import your actual reducers
export function renderWithProviders(
ui,
{
preloadedState = {},
store = configureStore({ reducer: { user: userReducer }, preloadedState }),
...renderOptions
} = {}
) {
function Wrapper({ children }) {
return <Provider store={store}>{children}</Provider>;
}
return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
}You can then use this helper in your test files to supply mock initial state:
import { screen } from '@testing-library/react';
import { renderWithProviders } from './test-utils';
import UserProfile from './UserProfile';
test('renders user profile with mock state', () => {
const mockState = {
user: { name: 'John Doe', loggedIn: true }
};
renderWithProviders(<UserProfile />, { preloadedState: mockState });
expect(screen.getByText('John Doe')).toBeInTheDocument();
});Method 2: Mocking React-Redux Hooks Directly
If you want to isolate a component completely without setting up a
store, you can mock the useSelector and
useDispatch hooks directly using Jest. This method is ideal
for quick unit tests.
Mocking useSelector
To control the data your component reads from the Redux store, mock
useSelector to return your desired mock state:
import { screen, render } from '@testing-library/react';
import * as reactRedux from 'react-redux';
import UserProfile from './UserProfile';
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn(),
}));
test('displays mock user data', () => {
// Setup the mock implementation for useSelector
reactRedux.useSelector.mockImplementation((selectorFn) =>
selectorFn({ user: { name: 'Jane Doe' } })
);
render(<UserProfile />);
expect(screen.getByText('Jane Doe')).toBeInTheDocument();
});Mocking useDispatch
To test if your component dispatches the correct actions, mock
useDispatch to return a Jest spy function:
import { screen, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import * as reactRedux from 'react-redux';
import LogoutButton from './LogoutButton';
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useDispatch: jest.fn(),
}));
test('dispatches logout action on click', async () => {
const mockDispatch = jest.fn();
reactRedux.useDispatch.mockReturnValue(mockDispatch);
render(<LogoutButton />);
const button = screen.getByRole('button', { name: /logout/i });
await userEvent.click(button);
expect(mockDispatch).toHaveBeenCalledWith({ type: 'user/logout' });
});