Sharing and Testing Code in React with Higher Order Components

Posted on by in Development, Web

Higher Order Components (HoC) in React can be simple to use and test. If you haven’t read about HoC’s and how and why they’ve replaced mixins, check out this great Medium post by Dan Abramov.

Most of the resources and examples that I found online about higher order components are complex, and don’t include a testing solution. This is a super simple example designed to demonstrate how we can generalize React components using Higher Order Components and unit test them. We will be using ES6 syntax and Enzyme to test.

No HoC’s

Let’s start the example with two Components, a UserList and a PokemonList. In this naive example, the two lists have a different number of columns, and different column headers, but share the same selection behavior.

Components

Entry

The code to fetch the data is unsharable for… reasons. Let’s just pretend, ok? Looking at the rest of the class, however, it’s painfully obvious that we need to extract this shared code.

Higher Order Components

Now, let’s extract the selection code! In the example below, have extracted the common code into a higher order component called ListWrapper. The HoC is created inside a function that accepts another component. Inside the function, the HoC is defined and returned.

Components

Entry

Notice that selection and onSelect used to be state values on the original components, but are now props that are passed from the ListWrapper. In the entry file, we are now calling the listWrapper function on our components and rendering that into the DOM rather than invoking render on our component directly. Do not wrap your components before this! It won’t allow you to unit test all parts individually.

That’s it, really. What’s that? You want to unit test your code you say? That’s what I like to hear!

Testing!

To unit test these components, we will use a AirBnB’s shallow rendering library, Enzyme.

Again, I have not wrapped the list components before exporting them above. This allows us to test the HoC and component behavior separately.

Testing the HoC

In order to unit test the ListWrapper, I create a MockListComponent with no behavior in the before block. I wrap the dummy component with using the listWrapper function, and then use Enzyme’s shallow to shallow render it into the DOM.

The rest is just Jasmine.

Testing the Components

Because we didn’t wrap the list components, we can now unit test them as we normally would. We have to pass in our props before we render the component because we are enforcing propTypes.

I added a sample spec just to demo how we would use the onSelect spy if we needed to.

Easy and Testable

Higher Order Components are fairly easy to use and testable. Just make sure you actually need one before using it. Trying to wedge in a HoC where it’s not needed can be a painful process.

Good luck and happy coding!


Feedback

  Comments: 2

  1. Kamaraju prathi


    How do you test the Entry where you are actually using the Listwarpper applied


  2. In *Testing the HoC* `list_wrapper_spec.js`, where is `ListComponent` defined? It is declared at line 7 but I can’t see that a value is assigned before it gets into `shallow` at line 18. How does that work?
    “`
    var wrapper, ListComponent, MockListComponent, instance, set;
    [ … ]
    wrapper = shallow();
    “`

Your feedback