How to Mock Redux Reducers in React

Testing React applications that use Redux often requires isolating components from the actual global state. This guide demonstrates how to mock Redux reducers and store states in your Jest and React Testing Library setups. You will learn the best practices for mocking reducer behaviors, creating mock stores, and overriding initial states to ensure clean, reliable tests.

Why Mock Redux Reducers?

Reducers are pure functions that take the current state and an action, then return a new state. Because they are pure, unit testing a reducer directly does not require mocking; you simply pass inputs and assert the outputs.

However, when integration testing React components wrapped in a Redux <Provider>, you must control the state the components read. Mocking the reducers or the store allows you to: * Set up specific state scenarios (e.g., logged-in vs. logged-out states). * Avoid executing complex reducer logic during component tests. * Verify how components react to state changes.


The official Redux recommendation is to avoid mocking the reducer functions directly. Instead, create a real Redux store in your test environment but pass a mocked preloadedState. This ensures your components interact with a real Redux flow while using your test data.

1. Create a Custom Render Function

Set up a helper function in your testing utility file to wrap components with a Redux Provider containing a custom-configured store.

// test-utils.jsx
import React from 'react';
import { render } from '@testing-library/react';
import { configureStore } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';
import userReducer from './userSlice';

export function renderWithRedux(
  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 }) };
}

2. Use the Custom Render in Tests

Now, you can mock the reducer’s state by passing your desired state object as preloadedState.

// UserProfile.test.jsx
import React from 'react';
import { screen } from '@testing-library/react';
import { renderWithRedux } from './test-utils';
import UserProfile from './UserProfile';

test('renders user profile with mocked Redux state', () => {
  const mockState = {
    user: {
      name: 'John Doe',
      isLoggedIn: true,
    },
  };

  renderWithRedux(<UserProfile />, { preloadedState: mockState });

  expect(screen.getByText('Welcome, John Doe')).toBeInTheDocument();
});

Method 2: Mocking Reducer Functions with Jest

If you must mock the actual reducer function itself—for instance, to prevent it from running during a test or to spy on its calls—you can use Jest’s module mocking capabilities.

// userSlice.js
const initialState = { name: 'Guest' };
export default function userReducer(state = initialState, action) {
  switch (action.type) {
    case 'SET_USER':
      return { ...state, name: action.payload };
    default:
      return state;
  }
}

In your test file, intercept the reducer file import and replace the default export with a mock function:

// UserComponent.test.jsx
import userReducer from './userSlice';

// Mock the entire slice module
jest.mock('./userSlice', () => {
  return {
    __esModule: true,
    default: jest.fn(() => ({ name: 'Mocked Jest User' })),
  };
});

test('uses the mocked reducer output', () => {
  // The mocked reducer will now return 'Mocked Jest User' 
  // regardless of the action dispatched.
  expect(userReducer()).toEqual({ name: 'Mocked Jest User' });
});

Method 3: Mocking with redux-mock-store

For scenarios where you only want to test if correct actions are dispatched without mutating the state, you can use the redux-mock-store library.

1. Install the library

npm install redux-mock-store --save-dev

2. Configure and use the mock store

import configureStore from 'redux-mock-store';
import { Provider } from 'react-redux';
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';

const mockStore = configureStore([]);

test('should dispatch action on button click', () => {
  const store = mockStore({
    myReducer: { data: 'initial' },
  });

  render(
    <Provider store={store}>
      <MyComponent />
    </Provider>
  );

  // Assert actions dispatched to the mock store
  const actions = store.getActions();
  expect(actions).toEqual([]);
});