Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Using Jest and RTL with React and TypeScript

February 10, 2021
reacttypescript

In previous posts we have configured a React and TypeScript app to be bundled by Webpack 5. Our Webpack configuration included the handling of CSS and images.

In this post, we will install and use Jest and React Testing Library to write tests on a couple of components in our app.

Installing Jest And React Testing Library

We’ll start by installing Jest and its TypeScript types:

npm install --save-dev jest @types/jest

We can now install React Testing Library:

npm install --save-dev @testing-library/react

We will also install jest-dom which gives us useful matchers to use on the DOM.

npm install --save-dev @testing-library/jest-dom

Let’s add a npm script to run our Jest tests in package.json:

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

Configuring Jest

We can import jest-dom in a Jest setup file so that we don’t have to import it into each test file.

First, we will create the a Jest setup file in the root of the project called jest-setup.ts. We’ll add the following import statement into it:

import '@testing-library/jest-dom'

We can tell Jest about the setup file in its configuration section in package.json. Add the following jest field to package.json:

{
  ...,
  "jest": {
    "setupFilesAfterEnv": [
      "<rootDir>/jest-setup.ts"
    ]
  }
}

Creating a test

Let’s create a test for the Header component in a file called Heading.test.tsx:

import React from "react";
import { render, screen } from "@testing-library/react";
import { Heading } from "./Heading";

test("Header contains correct text", () => {
  render(<Heading />);
  const text = screen.getByText("My React and TypeScript App");
  expect(text).toBeInTheDocument();
});

The test checks that the content of the heading is correct.

If we run npm test to execute the test, we get a “Unexpected token ’.‘” error:

CSS module Jest error

The problem is that Webpack isn’t executed in a Jest test, so the CSS module hasn’t been resolved.

Mocking CSS modules

We aren’t testing the specific styles from the CSS module in the Header component, so we can mock this out using moduleNameMapper and a library called identity-obj-proxy.

Let’s install identity-obj-proxy:

npm install --save-dev identity-obj-proxy

Let’s add the following to Jest configuration in package.json:

{
  ...,
  "jest": {
    ...,
    "moduleNameMapper": {      "\\.(css|less)$": "identity-obj-proxy"    }  }
}

When Jest comes across the {heading.heading} class name, identity-obj-proxy will replace it with 'header', which mocks the CSS module out.

If we rerun the test, it passes:

Header test pass

Mocking images

Let’s create a test for the Content component in a file called Content.test.tsx:

import React from "react";
import { render, screen } from "@testing-library/react";
import { Content } from "./Content";

test("Content contains var image", () => {
  render(<Content />);
  const car = screen.getByAltText("Car");
  expect(car).toBeInTheDocument();
});

If we rerun our tests (npm test), we get a “Invalid or unexpected token” error:

Jest image error

The problem is that Jest doesn’t understand the image import.

Our test is only checking that an image element is contained within the Content component. So, we can mock the specific car image path using moduleNameMapper in the Jest configuration. Add the following to package.json:

{
  ...,
  "jest": {
    "moduleNameMapper": {
      ...,
      "\\.(jpg|jpeg|png|gif)$": "<rootDir>/src/__mocks__/fileMock.ts"    }
  }
}

Let’s add the following content in our mock file at src/__mocks__/fileMock.ts:

export default "test-file-stub";

Image paths in our React components will now be replaced with “test-file-stub” in our Jest tests.

If we rerun our tests (npm test), they will now pass:

Jest image pass

Nice! 😊

That’s it! Our React and TypeScript project now has some passing tests.

This code is available in GitHub at https://github.com/carlrip/react-typescript-jest-webpack.

Did you find this post useful?

Let me know by sharing it on Twitter.
Click here to share this post on Twitter

If you to learn more about using TypeScript with React, you may find my course useful:

Using TypeScript with React

Find out more