Advanced testing in React Native with Jest: Redux integration

redux jest integration

This post is part of my series on unit testing with Jest in React Native. You can find the introduction here.

By now you should have a solid understanding of how testing works in React Native. But there is one important concept left to go over, that is integrating redux into your tests. Redux is the industry standard for global state management in React applications. Even though React Context is supposed to replace Redux, it is not there yet. So how do we test Redux-connected components with Jest and react-native-testing-library?

Sample component

To test our implementation, we will use this component:

This component grabs the count parameter from the state to display it and dispatches an INCREMENT action whenever you press the button. Simple enough.

Inline integration

If you do not have to do this often, you may use inline redux integration. To do this, you will need to install redux-mock-store library. This library provides a great interface to assert dispatched actions on your redux store and test your components. With it, you can write code like this in your tests:

In the describe section, we create a mockStore function. It will be used as a factory for mock stores. It can be extended with middlewares (thunk, for instance), but I will leave it as an exercise for the reader. Then, in the first test, we create a store with {count: 5} as the initial state. Next, we render the Counter (wrapped in Provider) to assert that it indeed renders 5.

The second test is a bit more confusing. We create the store the same way, but then we send a press event to the button. The button should dispatch an action on the store, which we assert later.

Overriding the render function

While the inline approach works perfectly well, this is not scalable and will result in a lot of repetition in a large codebase. To mitigate this, consider overriding the render function so it injects a Provider with a store for you. To achieve this, create a test-utils.js file and put this code in it:

We create the mock store the same way we created it in earlier tests. The difference is that now the same store will be used for all the tests, so consider filling in the real INITIAL_STATE from your root reducer. Then we define the reduxRender funciton, which will wrap everything in a Provider. Lastly, re-export everything from react-native-testing-library for convenience. Now look at the same tests from earlier, but using this new method:

Now, code became shorter and more readable without compromising the functionality, a win-win situation. Note the store.clearActions() on line 7: since we are using the same-store across tests, it is important to reset it after every test.

This is the last post in my series on React Native unit testing. I hope now you have an understanding why tests are important and how to write them for different purposes.

Get new content delivered to your mailbox:

2 comments

  1. abdullah | october 7, 2020

    Thanks lot!

  2. zephyr | march 8, 2021

    I’d been searching for about a week trying to find a decent tutorial on React-Native testing – these are by far the best – easy to understand, well explained, and very on point.
    Thanks very much!!

leave a comment