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.
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:
Now apparently,
- Mocha is the testing framework
- Enzyme is a testing utility for React components
- Should is the assertion library
- 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 find
ing 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:
the expected markup would be:
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?