Testing a React/Redux app can be a problem. Recently, with new tools being created every day, choosing the right tool has become harder than ever. In this article, I will show you how you can use Jest to get your tests done.
To get started with Jest, you can download the create-react-app package, which is a convenient way to bootstrap new personal projects.
$ npm install -g create react-app
$ create-react-app netguru-react-redux-1
$ cd netguru-react-redux-1 && npm start
Now you can launch your tests in the watch mode with:$ npm test
Which runs the following under the hood:$ jest --watch
In every React/Redux project, you need to create and test at least four things: reducer, actions, component, container. In this tutorial, we will take a look at the first two.
Let’s assume we have an app that loads the quotes from a remote server. Our reducer can look as follows:
Testing the reducer is pretty straightforward. No magic here.
Hint: we are using toEqual instead of toBe because we need to compare objects by value. The toEqual performs a deep equal, so it’s needed for objects or arrays.
It is a good practice to check whether the reducer outputs the desired initial state and to check if it returns the current state if an unknown action was dispatched. In other words, you’d rather want to check that it doesn’t lose the state while we perform an action on some other part of the state tree. Believe me, this simple check can sometimes save hours of debugging.
Our action is also very basic. As soon as we execute it, dispatches the FETCH_QUOTES_REQUEST so we can use it to show a loading indicator, for example.
Next, it calls the API and, depending on the response, it dispatches FETCH_QUOTES_SUCCESS with the data or FETCH_QUOTES_FAILURE.
To dispatch redux actions asynchronously we need to use redux-thunk apart from redux. One important thing here: we need to return the promise from our action so that Jest knows how to handle it and waits for it to resolve.
Things are getting interesting here. We need to test two scenarios: (1) the server responds with a valid response and (2) the server responds with an error. We use to simulate server responses the fetch-mock package, which has a really simple API. We also need redux-mock-store, which provides a useful method to check dispatched actions. Similarly to what we did in the action we also need to return the promise here to let Jest know how it should handle it.
Bear in mind that we need to call the fetchMock.restore(); method to reset the fetch mock and use a different response for our request in next test case. It’s good to put that kind of resets in the afterEach function, which is run after each test case – this way our tests will stay nice and clean.
Stay tuned for our future posts! We will test the React part of the app and use more of Jest‘s features to create a complete testing suite.