chrisrhyno2003 chrisrhyno2003 - 1 year ago 128
Node.js Question

Testing React components with a .jsx extension

I am new to the React framework and right now I am exploring the way to test components in React. I was following this example:
for setting up a unit testing framework for React using mocha and karma.

I realized that all my components had .jsx extensions and not .js, and I dug deeper. I understood the components need to be built before they could be imported/used.

I tried using this example:
. But this does not cover karma.

How do I use karma so that the jsx files are built and then imported?

I am using gulp for building the artifacts and my NodeJS version is 5.6

Answer Source

Here's a simple example for unit testing React components using Mocha, Chai, and a jsdom helper, which is used in place of a test runner like Karma.

You will need the following dependencies:

"dependencies": {
  "react": "^15.1.0",
  "react-dom": "^15.1.0"
"devDependencies": {
  "babel-preset-es2015": "^6.9.0",
  "babel-preset-react": "^6.11.1",
  "babel-register": "^6.9.0",
  "chai": "^3.5.0",
  "jsdom": "^9.3.0",
  "mocha": "^2.5.3"

It's also useful to have an npm script that points to mocha - npm run test will execute your tests:

"scripts": {
  "test": "./node_modules/.bin/mocha"

After you have your dependencies set up, you'll want a directory structure that looks like this:

├── /src
│   └── component-to-test.js
├── /test
│   ├── /unit
│   │   └── component-to-test.spec.js
│   ├── /util
│   │   └── jsdom.js
│   └── mocha.opts
├── .babelrc
└── package.json

We'll start off with your .babelrc file. You'll need Babel to transpile your JSX into JavaScript. If you want to use ES6 syntax (highly recommended), Babel will help with that too. I've included both of these presets in the devDependencies.


  "presets": ["es2015", "react"]

Next, we'll look at the jsdom helper. This is needed in order to render React components into an in-memory DOM, which is typically handled by a test runner like Karma.


(function () {
    'use strict';

    var jsdom = require('jsdom'),

    if (!global.window) {
        baseHTML = '<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>Tests</title></head><body></body></html>';
        window = jsdom.jsdom(baseHTML).defaultView;

        global.window = window;
        global.document = window.document;
        global.navigator = window.navigator;


In order to leverage this jsdom helper for use in our mocha tests, we'll need to set up a mocha.opts file that specifies a few configuration options. We'll add a compiler that will tell Babel to pre-process the tests, and we'll require the jsdom helper so React has a DOM to use to render components.


--compilers js:babel-register
--reporter spec
--ui bdd
--require ./test/util/jsdom.js

Finally, we can start testing React components. As an example, here is a simple component that we can test.


import React from 'react';

export default class TestComponent extends React.Component {
    render() {
        return (
            <div className="test-component">Here is a test component</div>

And here is a test suite that will test this component's markup.


import TestComponent from '../../src/test-component';
import {expect} from 'chai';

import React from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from '../../node_modules/react/lib/ReactTestUtils';

describe('Test Component', () => {
    let renderedNode;

    function renderComponent() {
        const componentElement = React.createElement(TestComponent),
            renderedElement = ReactTestUtils.renderIntoDocument(componentElement);

        renderedNode = ReactDOM.findDOMNode(renderedElement);

    beforeEach(() => {

    it('should exist with the correct markup', () => {
        expect(renderedNode.textContent).to.equal('Here is a test component');

At this point, the command npm run test should result in a single passing test.

And that's it! If you're looking for more advanced testing techniques, you can completely avoid the need for a jsdom helper and use shallow rendering for your tests. I highly recommend Enzyme if you want to take this approach.

Let me know if you have any questions!