It is always a good idea to unit-test your code. React is usually used to build front-facing applications, so End to End test are the first thing that come to mind. Fortunately, React is almost as easy to test at Component level.

First thing you should do is grab your favorite test runner and framework — I’m going to go with Chai and Mocha. Additional you will need react-addons-test-utils and you’re basically done — we can now test our application. But since we’re working with React we also need an additional utility to test he components themselves — Facebook suggests using enzyme by Air B&B and I totally agree.

Running the actual tests

Since we’re working with ES6 code (imports) we will need a test runner that is able to parse the code. One way is to bundle an test package with webpack and test that, but this only adds additional compilation step and more time. Instead we can tell mocha to use babel as its compile by calling:

mocha --compilers js:babel-core/register src/**/*.test.js

Don’t forget to add babel-core to your project with npm install --save-dev babel-core . Running the above command will run all the tests stored in *.test.js files stored inside src directory. You might have to adjust the command to suit your folder structure. You can also add the --watch flag to have the test running in watch node and re-running tests as your spec or component changes.

Testing rendered Components — enzyme

The enzyme utility provides you with a set of renderers, that you can use instead of ReactDOM.render() to render and test your components.

The two most common rendering utilities are:

shallow() — will only render the supplied Component, will not render child components

— will only render the supplied Component, will not render child components mount() — will render the whole tree of Components at supplied root and use all the life-cycle methods

The most basic example that checks if the element renders (and returns a DOM object with given class) is short and easy to understand:

import React from "react";

import { expect } from "chai";

import { shallow } from "enzyme"; import Player from "./Player.js"; // this is our component describe("<Player />", () => { it("the component should mount", () => {

const wrapper = shallow(<Player />); // just render it

expect(wrapper.find(".Player")).to.have.length(1);

});

});

Working with the “browser” — window and document objects

Our unit-tests will be running in NodeJS so things like window and document aren’t available. To get around the issue we can use jsdom — an JS implementation of the DOM and HTML standards. Using the library is quite simple and boils down to:

import jsdom from "jsdom"; describe("our component", function() {

let doc; beforeEach(() => {

doc = jsdom.jsdom("<!doctype html><html><body></body></html>");

global.document = doc;

global.window = doc.defaultView;

}); it("will mount", () => {

// `document` and `window` are now available to our component

});

}

Gotchas

If you’re using CSS Modules you will find out that importing the CSS/SCSS/LESS files into your components messes up the tests. To get around that, create a file named mocha.js and enter the following:

function noop () {

return null;

}

require.extensions[".css"] = noop;

Changing .css to other extensions if needed. You also need to run the test as:

mocha --compilers js:babel-core/register,./mocha.js src/**/*.test.js

to use the new compiler. It will simply skip loading all the CSS classes — we’ve no need to test them anyway.