How to Test Redux in React: Simple Guide with Examples
To test
Redux in React, use Jest with React Testing Library to render components wrapped in a Provider with a test store. Test actions, reducers, and component behavior by dispatching actions and checking rendered output or state changes.Syntax
Testing Redux in React involves three main parts:
- Store setup: Create a test Redux store with your reducers.
- Provider wrapper: Wrap your React component with
Providerfromreact-reduxto give access to the store. - Render and test: Use
React Testing Libraryto render the component and test UI or state changes after dispatching actions.
javascript
import { render } from '@testing-library/react'; import { Provider } from 'react-redux'; import { configureStore } from '@reduxjs/toolkit'; import reducer from './reducer'; import MyComponent from './MyComponent'; const store = configureStore({ reducer }); render( <Provider store={store}> <MyComponent /> </Provider> );
Example
This example shows testing a simple counter component connected to Redux. It tests if clicking the increment button updates the displayed count.
javascript
import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import { Provider, useSelector, useDispatch } from 'react-redux'; import { configureStore, createSlice } from '@reduxjs/toolkit'; // Redux slice const counterSlice = createSlice({ name: 'counter', initialState: { value: 0 }, reducers: { increment: state => { state.value += 1; } } }); const { increment } = counterSlice.actions; // React component function Counter() { const count = useSelector(state => state.counter.value); const dispatch = useDispatch(); return ( <div> <span>Count: {count}</span> <button onClick={() => dispatch(increment())}>Increment</button> </div> ); } // Test test('increments counter on button click', () => { const store = configureStore({ reducer: { counter: counterSlice.reducer } }); render( <Provider store={store}> <Counter /> </Provider> ); expect(screen.getByText(/Count:/).textContent).toBe('Count: 0'); fireEvent.click(screen.getByText('Increment')); expect(screen.getByText(/Count:/).textContent).toBe('Count: 1'); });
Output
PASS increments counter on button click
Common Pitfalls
- Not wrapping components with
Providercauses errors because Redux store is missing. - Using the real store instead of a test store can make tests flaky or slow.
- Testing implementation details like internal state instead of UI output or dispatched actions reduces test reliability.
- For async actions, forgetting to use async utilities like
waitForcan cause tests to fail.
javascript
/* Wrong: Missing Provider wrapper */ // render(<Counter />); // This will error /* Right: Wrap with Provider and test store */ // render(<Provider store={store}><Counter /></Provider>);
Quick Reference
- Use
configureStorefrom Redux Toolkit to create a test store. - Wrap components with
Providerpassing the test store. - Use
React Testing Libraryto render and interact with components. - Test UI changes or dispatched actions, not internal Redux state directly.
- For async Redux logic, use async testing helpers like
waitFor.
Key Takeaways
Always wrap tested components with Redux
Provider and a test store.Use Redux Toolkit's
configureStore for easy test store setup.Test user-visible UI changes after dispatching Redux actions.
Avoid testing Redux internals; focus on component behavior.
Use async testing utilities for async Redux actions.