Writing Tests#
Because most of the Redux code you write are functions, and many of them are pure, they are easy to test without mocking.
Setting Up#
We recommend Jest as the testing engine. Note that it runs in a Node environment, so you won't have access to the DOM.
To use it together with Babel, you will need to install babel-jest:
and configure it to use babel-preset-env features in .babelrc:
Then, add this to scripts in your package.json:
and run npm test to run it once, or npm run test:watch to test on every file change.
Action Creators#
In Redux, action creators are functions which return plain objects. When testing action creators, we want to test whether the correct action creator was called and also whether the right action was returned.
Example#
can be tested like:
Async Action Creators#
For async action creators using Redux Thunk or other middleware, it's best to completely mock the Redux store for tests. You can apply the middleware to a mock store using redux-mock-store. You can also use fetch-mock to mock the HTTP requests.
Example#
can be tested like:
Reducers#
A reducer should return the new state after applying the action to the previous state, and that's the behavior tested below.
Example#
can be tested like:
Components#
First, we will install React Testing Library. React Testing Library is a simple and complete React DOM testing utility that encourage good testing practices. It uses react-dom's render function and act from react-dom/tests-utils.
If you are using jest as recommended above, we also recommend installing jest-dom as it provides a set of custom jest matchers that you can use to extend jest. These will make your tests more declarative, clear to read and to maintain. jest-dom is being used in the examples below.
Consider the following App component:
To test the component, we render it into the DOM and pass stubbed callbacks as props, then we assert whether the callbacks were called when expected. We can use the wrapper option in the render function and export our own render function as explained in React Testing Library's setup docs.
Our render function can look like this:
And our test can use our exported render function:
Middleware#
Middleware functions wrap behavior of dispatch calls in Redux, so to test this modified behavior we need to mock the behavior of the dispatch call.
Example#
First, we'll need a middleware function. This is similar to the real redux-thunk.
We need to create a fake getState, dispatch, and next functions. We use jest.fn() to create stubs, but with other test frameworks you would likely use Sinon.
The invoke function runs our middleware in the same way Redux does.
We test that our middleware is calling the getState, dispatch, and next functions at the right time.
In some cases, you will need to modify the create function to use different mock implementations of getState and next.
Glossary#
React Testing Library: React Testing Library is a very light-weight solution for testing React components. It provides light utility functions on top of react-dom and react-dom/test-utils, in a way that encourages better testing practices. Its primary guiding principle is: "The more your tests resemble the way your software is used, the more confidence they can give you."
React Test Utils: ReactTestUtils makes it easy to test React components in the testing framework of your choice. React Testing Library uses the
actfunction exported by React Test Utils.