How to test High Order Components in React
Tags: redux, webdev, testing, javascript
Published: 2018-08-13 02:16:01

---
title: How to test High Order Components in React
published: true
description: How to test High Order Components in React
tags: #redux #webdev #testing #javascript 
---

## Intro

**Note**: I'm assuming you are somewhat familiar to unit testing in JavaScript and know what a High Order Component is.

I'm adding unit tests to one of my pet Projects. I'm using `react-boilerplate` as a starter app, so Enzyme and Jest are already plugged in.

This is a brief walk trough for a problem I just encountered.

## The problem
Testing HOCs, is a quite particular scenario, since it is uses `mapStateToProps` and a High Order component, of course.

Let's take your classic `Authentication` component. It reads a `boolean` from state, and evaluates whether the user is authenticated or not, and returns the component or redirects to a given URL accordingly.

This is what our component looks like:

```javascript

/**
 *
 * Auth.js
 *
 */

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { bindActionCreators } from 'redux';
import PropTypes from 'prop-types';

export default function(ComposedComponent) {
  class Authentication extends Component {
    /* eslint-disable */
    componentWillMount() {
      if (this.props.authenticated === false) {
        return this.props.changePage();
      }
    }

    componentWillUpdate(nextProps) {
      if (nextProps.authenticated === false) {
        return this.props.changePage();
      }
    }
    /* eslint-enable */

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  Authentication.propTypes = {
    authenticated: PropTypes.bool,
    changePage: PropTypes.func,
  };

  const mapStateToProps = state => ({ authenticated: state.user.isLoaded });

  const mapDispatchToProps = dispatch =>
    bindActionCreators({ changePage: () => push('/login') }, dispatch);

  return connect(
    mapStateToProps,
    mapDispatchToProps,
  )(Authentication);
}

```

## The solution
For the store, we well use a sweet library that allows us to mock a Redux store, as you can imagine, it is called `redux-mock-store`.

`yarn add redux-mock-store --dev`

Then our test should do the following:
1. Create a basic store, with the property that our HOC needs to map to. In this scenario, is `store.user.isLoaded`. 
2. Creeate a component which the `Auth` should render when the user is authenticated.
3. Assert that it returns(or renders) something.

Lets go step by step.

```javascript



import configureStore from 'redux-mock-store';
import Auth from './Auth';


let store;

describe('<Auth /> test', () => {
  beforeEach(() => {
    const mockStore = configureStore();

    // creates the store with any initial state or middleware needed
    store = mockStore({
      user: {
        isLoaded: true,
      },
    });
...
```

Notice that mockStore is taking as an argument, what our state should look like. Since `Auth` only cares about `user.isLoaded`, we'll set it as true and evaluate that `Component` is being rendered. We'll use the most generic I can think of at this time.


```javascript
// Auth.spec.js
...
  it('Should render the component only when auth prop is true', () => {
    const Component = <h1>Hola</h1>;
    const ConditionalComponent = Auth(Component);
    const wrapper = shallow(<ConditionalComponent store={store} />);
    expect(wrapper).not.toBe(null);

```

We just need to pass as a prop the store we just created, and then assert that our component is being rendered.

Our test in one single file.


```javascript

/**
 *
 * Auth.spec.js
 *
 */

import React from 'react';
import { shallow } from 'enzyme';
import configureStore from 'redux-mock-store';

import Auth from '../Auth';

let store;

describe('<Auth />', () => {
  beforeEach(() => {
    const mockStore = configureStore();

    // creates the store with any initial state or middleware needed
    store = mockStore({
      user: {
        isLoaded: true,
      },
    });
  });
  it('Should render the component only when auth prop is true', () => {
    const Component = <h1>Hola</h1>;
    const ConditionalHOC = Auth(Component);
    const wrapper = shallow(<ConditionalHOC store={store} />);
    expect(wrapper).not.toBe(null);
  });
});

```


## Conclusion

This test covers just one scenario, but all the assertions needed can start from here.

Cheers.