Testing a React app in Node.js with Jasmine

The Jasmine NPM package was originally designed just to run specs against your Node.js code, but with a couple of other packages, you can use it to run your React specs as well. This tutorial assumes you’re using babel to compile your code and React Testing Library to test it. We’ll also be using jsdom to provide a fake HTML DOM for the specs.

A complete working example of this setup is also available.

Choose the package managment tool you’ll be using:


Basic setup

Install these packages if you haven’t already:

$ yarn add --dev @babel/core \
                 @babel/register \
                 babel-preset-react-app \
                 cross-env \
                 jsdom \
                 jasmine
$ npm install --save-dev @babel/core \
                         @babel/register \
                         babel-preset-react-app \
                         cross-env \
                         jsdom \
                         jasmine

Then initialize Jasmine:

$ yarn run jasmine init
$ npx jasmine init

That command will create spec/support/jasmine.json and populate it with an initial default configuration. With Jasmine initialized, the first thing we’ll do is make a helper to register babel into the require chain. This will cause TypeScript files to be compiled to Javascript on the fly when they’re loaded. Make a new file called babel.js in the spec/helpers directory:

require('@babel/register');

Or, if using TypeScript:

require('@babel/register')({
    "extensions": [".js", ".jsx", ".ts", ".tsx"]
});

We need to tell Babel what flavor of Javascript we want by adding a Babel configuration with the following contents:

{
  "presets": ["react-app"]
}

Next, we need to provide a simulated browser environment. Create jsdom.js in spec/helpers with the following contents:

import {JSDOM} from 'jsdom';

const dom = new JSDOM('<html><body></body></html>');
global.document = dom.window.document;
global.window = dom.window;
global.navigator = dom.window.navigator;

In order to ensure these files are loaded before any specs run, we’ll edit spec/support/jasmine.json. We need the Babel helper to be loaded before any helpers that contain TypeScript, JSX, or any other code that needs to be transpiled, so we modify jasmine.json like so:

"helpers": [
  "helpers/babel.js",
  "helpers/**/*.js"
],

Or, if using Typescript:

"helpers": [
  "helpers/babel.js",
  "helpers/**/*.{js,ts}"
],

Next, set up the test script in package.json to run Jasmine:

  "scripts": {
    "test": "cross-env NODE_ENV=test jasmine",

Handling CSS and image imports

It’s common for React code to import CSS or image files. Normally those imports are resolved at build time but they’ll produce errors when the specs are run in Node. To fix that, we add one more package:

$ yarn add --dev ignore-styles
$ npm install --save-dev ignore-styles

And put the following code in spec/helpers/exclude.js.

import 'ignore-styles';

Optional: Spec file pattern configuration

You also might want to change the way that Jasmine looks for spec files. Jasmine traditionally looks for files in the spec directory with names ending in .spec.js, but a common convention in React projects is to put spec files in the same directories as the code they test and give them names ending in .test.js. If you want to follow that convention, change the spec_dir, spec_files, and helpers setting in spec/support/jasmine.json accordingly:

  "spec_dir": "src",
  "spec_files": [
    "**/*.test.*"
  ],
  "helpers": [
    "../spec/helpers/babel.js",
    "../spec/helpers/**/*.js"
  ],

Or, for TypeScript:

  "spec_dir": "src",
  "spec_files": [
    "**/*.test.*"
  ],
  "helpers": [
    "../spec/helpers/babel.js",
    "../spec/helpers/**/*.{js,ts}"
  ],

Setting up a React testing utility

We’ll need a way to render React components and inspect the result. There are several utility libraries that provide that functionality. The most popular is React Testing Library.

Setup for react-testing-library is simple. All we need to do is make sure the @testing-library/react package is installed. If you used a recent version of create-react-app to initialize your application, it might already be there. If not, install it:

$ yarn add --dev @testing-library/react
$ npm install --save-dev @testing-library/react

See the React Testing Library documentation for more information. The related jasmine-dom matcher library may also be of interest.

Note that most of the React Testing Library docs are written for Jest, so the code samples require some translation before they’ll work in Jasmine. In particular:

When translating code samples from Jest to Jasmine, you may find it helpful to refer to the Jasmine tutorial, the list of matchers that come with Jasmine, and the list of matchers that come with jasmine-dom.

Wrapping up

You’re all set. Write your specs and run them:

$ yarn test
$ npm test