Writing tests for React components, using Mocha, Enzyme and Should.js, can feel a bit like trying to do this toddlers’ puzzle, inside a black velvet bag.

toddlers shape sorter

Try this shape? Nope. How about this one? Nope. Maybe this one? Ok, that seems to work, but - I can’t see the shape it is - so I don’t know why it fitted.

Time to learn what is really going on here.


Our tests usually look something like this:

describe('Button component', () => {
  it('should set the button size to large', () => {
    const renderDom = mount(<Button size="large">Button</Button>);
    renderDom.find('a').get(0).getAttribute('class').should.containEql('button_large');
  });
});

Now apparently,

  1. Mocha is the testing framework
  2. Enzyme is a testing utility for React components
  3. Should is the assertion library
  4. jsdom is a JavaScript based headless browser which we render components into using the mount function

Mocha is used for the describe and it lines in the example above. These parts are always the same for our tests, so I don’t feel the need to look any further into this here.

Enzyme is the rendering bit (ie, the mount) and all the different ways of traversing the DOM and finding various bits of what was rendered. It’s the part I’m mainly going to be looking at here.

Should is the ‘assertion library’ - meaning, it’s the library used to evaluate the actual to the expected outcome - it’s the heart of the test itself really.

Pinpointing what needs to be tested

I want to test my Button component, to ensure the value of the size prop makes the resulting markup have a class of button_large. So, assuming I have mounted the following:

<Button size="large">Button</Button>

the expected markup would be:

<a href="" className="button_large">Button</a>

This is where Enzyme comes in, to pinpoint what you want to find, and in this case, it’s the node a. But the a tag is also the only node in our mounted markup (ie, at position 0):

  • find('a')
  • get(0)

For find('') you can use the following selectors:

  • class syntax (.foo, .foo-bar, etc.)
  • tag syntax (input, div, span, etc.)
  • id syntax (#foo, #foo-bar, etc.)
  • prop syntax ([htmlFor="foo"], [bar], [baz=1], etc.);

For get() - it’s simply the position of the node, ie, if it’s the fourth node in the DOM, then get(3) because it’s a zero based index.

Now we’ve found the node that we want to inspect, we need to find the specific bit that we want to evaluate within it. In this case it’s the value of a class:

get(0).getAttribute('class')

Obviously, this could be any valid attribute of the tag in question, such as href, type etc.

And finally, the evaluation is done by Should syntax, where we need the following:

should.containEql('button_large')

The Should.js assertion library contains a myriad of evaluating statements, some of which we’ve used are:

  • should.have.length(2)
  • should.equal('Foo')
  • should.containEql(style.Bar)
  • should.not.containEql("dropdown_show")
  • should.startWith('button')

Read Richard Kotze’s post here on the Findmypast Tech Blog: Testing react using enzyme to learn much more.

The exercise of writing this has made the puzzle of Mocha + Enzyme + Should a lot clearer in my head. Did it help you?