5-Dec

React

Testing of React component with a real Redux store

Do you avoid testing of components that depend on Redux because you fear the complexity? Are you loosing sleep worrying about configuring huge mock stores for testing the simplest of components? Fear no moarrr!

1 min read

·

By Aleksander Sjåfjell, Kjetil Børs Lind

·

December 5, 2018

The easiest solution will in some cases be to configure the original Redux store with your favorite root reducer as you would in real life production code. It's actually not that complicated!

The component under testing

Let's say you've made a React component that renders a Christmas wish list. The wishes comes from the Redux store:

import React from "react";

const MySantaWishList = ({ wishes }) => (
  <ul>
    {wishes.map((wish, index) => (
      <li id={`wish_${index}`} key={index}>
        {wish}
      </li>
    ))}
  </ul>
);

const mapStateToProps = ({ state }) => ({
  wishes: state.wishes,
});

const MyConnectedWishes = connect(mapStateToProps)(MySantaWishList);

Wishes can be added to the list by dispatching an action with type ADD_WISH and data like Buy sexy Santa outfit. If working as intended, the component should update the wish list when this action is dispatched.

Testing the component with a real Redux store

Let us make testing of the component as close to reality as we possibly can. How? By skipping the creation of a mock store and making a real one. The following snippet shows how to set up the store together with the component, just like in production code:

const store = configureStore(rootReducer);
const MyTestSantaWishList = mount(
  <Provider store={store}>
    <MySantaWishList />
  </Provider>
);

So, to test that the component behaves correctly:

MyTestSantaWishList.props().store.dispatch({
  type: ADD_WISH,
  data: "Buy sexy Santa outfit",
});

expect(MyTestSantaWishList.find("#wish_0").text()).toEqual(
  "Buy sexy Santa outfit"
);

Awesome? We think so!