Setting up testing for React Apps using jest & react-testing-library

Setting up testing for React Apps using jest & react-testing-library

for react projects created using custom webpack configurations

Hello,

I'm back after a long time with another article. I had lot of interviews lined up as I was looking for switching job. Finally, accepted a position as Associate 2 at Pricewaterhouse Coopers.

So as one of the first tasks, I was asked to setup testing for react app that we were building using Jest and React Testing Library. I ran into multiple issues with the setup and could not find quick fixes for my problems. Just documenting what I did so that others don't feel or get stuck.

Key Points to be noted

  • This solution is for projects being bundled with webpack
  • This article is not for people who are bootstrapping the React App with create-react-app (hereby referred in the article as CRA). CRA comes preconfigured with jest and react-testing-library.
  • There are few things in this article which even I don't understand like creating stubs and various parameters in jest.config.js file
  • You have a basic knowledge of what packages like babel & webpack do
  • You have a react project created using webpack. If not start by cloning using below command
git clone -b 01-starter https://github.com/ttahm3d/react-javascript-template.git

Getting started

As is the way with CRA template, most of the react app testing has been moved away from the combo of Jest and Enzyme to Jest and React Testing Library. Most of this due to the fact that enzyme does not support most of the new features of react and the delay in getting apapted to new features.

For someone coming from a Enzyme testing background, there is a complete shift in the testing point-of-view. We test the component for the way it works in React-Testing Library.

Installation

Jest is a javascript testing framework. It acts as a test runner and provides us methods to interact and assert if the expected results are correct or false.

npm install --save-dev jest

Let's check if it works by running the tests specified in the Jest Docs

// Sum.js
function Sum(a, b) {
  return a + b;
}

export default Sum;

// Sum.test.js
import Sum from './Sum';

test('2 and 2 is 4', () => {
  expect(Sum(2, 2)).toBe(4);
});

Add the below settings to package.json

    "scripts": {
        ...,
        "test": "jest",
    },

Now run npm run test.

This test should work as expected. Lets install the other part of testing suite react-testing-library and start writing tests for our React components.

npm install @testing-library/react @testing-library/jest-dom @testing-library/user-event

Configuration

Before we test React components we need to configure jest and react-testing-library. Run the command:

npx jest --init

You will be taken through a series of questions in the command line, answer them as per the applicability. For our instance the response is as below in the screenshot. After this is done, a jest.config.js file is created which has various parameters that are result of your choices.

image.png

The Problem

Create a new test file app.test.js and the below contents

import { render, screen } from '@testing-library/react';
import App from './app';

it('should render the app component', () => {
  render(<App />);
  const text = screen.getByText(/React starter/i);
  expect(text).toBeInTheDocument();
});

Now we see an error with error message on the as below

image.png

This is because jest cannot parse non Javascript files using babel loader. Files such as images, fonts, css files etc. need to be stubbed as per the jest documentation. We need to use the property called moduleNameMapper to stub these files.

Solution

Create a folder named Mocks and create two files fileMock.js and styleMock.js

Add the below content to respective files

// fileMock.js
module.exports = "test-file-stub";

// styleMock.js
module.exports = {}

Now to the jest.config.js add the below content

module.exports = {
...,
    moduleNameMapper: {
        "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
            "<rootDir>/Mocks/fileMock.js",
        "\\.(css)$": "<rootDir>/Mocks/styleMock.js",
    },
};

There is a new error now which is as below

image.png

Create a new file setupTests.js and add the following content

import '@testing-library/jest-dom/extend-expect`

and add the below to jest.config.js

module.exports = {
   ...,
  setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
}

What this does it it calls the setupTests.js file before jest runs every .test file. Now the tests would run and pass.

image.png

Complete soultion is in this Git repo

Thats all for this article. Thanks for reading it through.