Testing with Jest and React Testing Library

Last Updated:
Mocking A React Component In Jest

I have written a number of posts on small niche problems within Jest. From checking if a child component is passed the correct props, to how to correctly mock out the Intl API.

Every time I went to write one of these posts I initially began with an introduction to Jest and React Testing Library. This would then get removed as the piece got more fleshed out.

To fill that gap I have put together this guide/overview of UI testing with Jest and React Components.

What is Jest?

In a brief overview, Jest is an open-source JavaScript testing framework that is widely used with React.

Amongst other things, Jest can be used to create mock functions which can be used to test the behaviour of your React components, take snapshots of UI to check for changes or regressions, and check that flows work in the way that a user will use them.

All tests have a unique global state, which means they can be run in parallel with no overlapping concerns. The beauty of Jest is that it is well-documented and requires little configuration.

A very minimal example of a Jest test looks like this:

import myTest from "./my-test.js"

describe("all the tests for my test function", () => {
  test("has a specific case or flow to check", () => {
    expect(myTest()).toBe("Some outcome");
  });
});

Breaking down what is happening above, we can see:

  • describe function = the test suite
  • test function = the test case
  • expect function = the test assertion

What is React Testing Library?

The React Testing Library is a lightweight library that provides a set of tools for testing React components. These testing functions sit on top of react-dom, and react-dom/test-utils. This means that the components being tested act in the same way as they would on a live production website.

You can use the React Testing Library to:

  • Test the rendering of your React components
  • Test the state of your React components
  • Test the interaction with your React components
  • Test the lifecycle of your React components

RTL has some super helpful query functions that do most of the heavy lifting for you. For a full overview I would recommend taking a look at their API documentation.

Most Used of React Testing Library Query Functions

Three of the more useful (in my opinion) query functions are:

byRole

Gets the dom element by role (or aria-role). Examples of these would be input, button or checkbox. You can also dial down into this a little more with the byRole options. If you wanted to get an image by its name <img aria-label="fancy image" src="fancy.jpg" /> you could do: getByRole('img', { name: 'fancy image' }). Take a look at the Jest documentation for more details.

byText

The byText utility function searches the dom in the text for any string with specific text. It can be used within getByText, queryByText, getAllByText, queryAllByText, findByText, and findAllByText. For more details see the Jest documentation.

byLabelText

The byLableText is similar to the byText query, but is aimed at input fields or similar. This makes it easier to find and add content to inputs, or check that they contain specific values.

Are Jest and React Testing Library the same?

What the difference was between Jest and React Testing Library. Should you use one over the other, i.e. React Testing Library vs. Jest.

Jest and React Testing Library can (and generally are when testing React components) be used together, as they both have different responsibilities. Jest is a test runner. It looks for all files ending with .test.js and runs each test. After running the tests it will return which tests passed or failed, and why they failed.

React Testing Library provides functions that help find and interact with specific DOM nodes within the component being testing. These functions also allow you to run actions on these components, such as:

  • rendering
  • fireEvent
  • waitFor
  • screen

How to Mock a Function with Jest

Mocking a function with Jest is relatively simple. It is a three step process.

  1. Import the dependencies
  2. Mock the dependency
  3. Fake the function output to test that the function works as required.

This follows the flow of three As in unit tests:

  • Arrange: set up the environment and the state of date for testing.
  • Act: call the test, and run the function to perfect the action.
  • Assert: Check that the output and side effects are returns as expected.

Read more about the three As of unit testing here.

Here is a simple example of a test laid out to follow the AAA pattern.

Function to test

import getFirstNumber from '../getFirstNumber';
const addNumber = (value) => {
    const result = getFirstNumber() + value;
    return result;
} 

Testing the function

// Import all the modules
import getFirstNumber from '../getFirstNumber';
import addTwoNumbers from '../addTwoNumbers';

// This is a function that is not being tested, so we mock it out
jest.mock('@../getFirstNumber');

describe('addTwoNumbers', () => {
    test('If getFirstNumber is 1, total is 3', () => {
        // Arrange
        getFirstNumber.mockReturnValue(1);

        const argA = 2;
        const assert = 3; // Act
        const result = addNumbers(argA); // Assert

        expect(result).toBe(assert);
    });
});

If you are looking to mock a whole React component I would suggest looking at this article on how to mock a React component in Jest.

Related Posts

Get helpful Jest Pieces right to your inbox

Keep up to date with all helpful bits of Jest snippets and articles.