DEV Community

Cover image for How To Unit Test React Applications with Jest: A Beginner's Guide
Mosunmola Balogun
Mosunmola Balogun

Posted on • Edited on

How To Unit Test React Applications with Jest: A Beginner's Guide

Testing plays a crucial part in ensuring the quality and reliability of your code. With the right knowledge of testing, its methods, and tools, you can ensure your code matches the requirements and is bug-free.

Testing is a critical aspect of software development, yet it is frequently overlooked and undervalued despite its vital role in ensuring the quality and reliability of applications. Testing is important because it helps identify bugs before a software product is released to its end users.

In this article, we'll cover what you need to know about unit testing, getting started with unit testing in your React applications using Jest, from setting up Jest in your project to writing tests.

Table of Contents

  1. What Is Unit Testing And Why Is It Important?
  2. Performing Unit Tests With Jest In React
  3. Mocking Functions With Jest
  4. Snapshot Testing With Jest
  5. Conclusion

What Is Unit Testing And Why Is It Important?

Unit testing is an aspect of the overall testing process in software development. It focuses on individual units of an application such as functions, objects, procedures, and so on. The primary purpose of unit tests is to ensure that each unit performs as expected.

From the definition above, we can deduce that unit testing in React is the testing of individual React components.

Why Is It Important?

Below are some important reasons why we need unit tests.

  1. Unit tests help to set the standard for coding requirements; writing tests while implementing a feature, for example, gives us an idea of how the implementation should be written.
  2. It prevents developers push bugs to production as it is always mostly detected in the development phase.
  3. Unit testing simplifies the debugging process.
  4. Cost-effective - It is cheaper to fix bugs way before a later stage, let's say after it has been pushed to production.

Performing Unit Tests With Jest In React

Jest is a JavaScript testing framework designed to ensure the correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar, and feature-rich API that gives you results quickly.

-Jest Core Team

Jest in itself is not a library but a framework, it even has a CLI tool that you can use with the command line. Its official website emphasizes its focus on simplicity and that's due to its zero config setup. You can start using it as soon as you install it.

Setup

  • Create a new React app

Open your terminal and create a new React app using the command below

npx create-react-app unit-testing-tutorial
Enter fullscreen mode Exit fullscreen mode
  • Install Jest using your favorite package manager

When you use cra(create-react-app) to create a new React project, it has built-in support for Jest, hence we do not have to install it manually. Hence, the only thing you need to do is install react-test-renderer for rendering snapshots which will also be covered in this article. You can install it with the command below.

with npm

npm install --save-dev react-test-renderer
Enter fullscreen mode Exit fullscreen mode

with yarn

yarn add --dev react-test-renderer
Enter fullscreen mode Exit fullscreen mode

Otherwise, if you are not using cra, you have to install it manually with your favorite package manager with the command below.

with npm

npm install --save-dev jest react-test-renderer
Enter fullscreen mode Exit fullscreen mode

with yarn

yarn add --dev jest react-test-renderer
Enter fullscreen mode Exit fullscreen mode

Next, add the following code to your package.json file

{
  "scripts": {
    "test": "jest"
Enter fullscreen mode Exit fullscreen mode

Testing A React Component

If you used cra to create your React app, a App.test.js file would have been created for you by default for testing the App.js component. To play around, you can run a sample test with the npm run test command on your terminal to see how testing works.

In the following steps, we'll get started with testing our own React component with Jest.

  • Step 1: Create a Component

Let's create a component and call it MyFirstTest, which simply renders hello with the name passed to its prop.

import React from "react";

function MyFirstTest({ name }) {
    return (
    <h1>Hello {name}!</h1>
    )
}

export default MyFirstTest;
Enter fullscreen mode Exit fullscreen mode
  • Step 2: Create A Test File

Next, we'll create a test file in the same directory as the component and use the extension .test.js. The .test.js extension lets Jest know that this is a test file.

The test will check if our component is rendered with the correct name passed to it as a prop. The unit test for our component MyFirstTest can then be written as seen below:

import { render } from '@testing-library/react';
import MyFirstTest from './MyFirstTest';

test('renders the component with the correct name passed as prop', () => {

  const { getByText } = render(<MyFirstTest name="Peter"/>);
  const textElement = getByText(/Hello Peter!/i);
  expect(textElement).toBeInTheDocument();

});

Enter fullscreen mode Exit fullscreen mode

We can describe the above test as:

  • We define a test case with the test function provided by Jest. The function takes a string that explains what the test is going to do as its first argument and the second argument is a callback function that implements the test logic.

  • Inside the callback function, the first thing we do is render the component we want to test with the render function. The render function returns an object that contains a lot of useful functions that can be used to interact with the rendered component.

  • From these functions, we utilize the getByText function. This function searches through the rendered component to find an element that contains the text "Hello Peter".

NOTE: The /i at the end of the string /Hello Peter!/i was used to indicate case insensitivity. Hence, "/i" matches the string "Hello Peter" regardless of the case. i.e HeLLo PETER will still match.

  • If the component is appropriately rendered, then the element exists in the virtual DOM. We use the expect function which gives us access to many matchers (like toBeInTheDocument()) to assert that the element is in the virtual DOM. If it asserts that it's present, the test will pass. Else, the test fails.

  • Run the test with npm run test command. Your test result should look like the image below.

Test Result

Mocking Functions With Jest

When a function is mocked, it means a sample or epitome of that function is created as a replacement for that function for the purpose of testing. Its purpose is to verify its result or behavior in a predictable environment.

Jest provides several ways we can perform mocking including jest.fn(), which we can use to ensure predictable results. With jest.fn() we can create a sample(mock function) that can be used to replace the original function for testing purposes. The mock function can then be configured to return specific values or throw new errors. By mocking functions, we can confirm that components are using functions as expected. Let's look at an example of how to mock a function using jest.fn() in the following steps.

  • Create a file math.js and copy the following code.
//math.js
export const add = (a, b) => a + b;
Enter fullscreen mode Exit fullscreen mode
  • Create another file add.js and import the add function from the math.js file and copy the code below. This way we don't have to worry about the implementation of how the addition is done in the math.js file.
import { add } from './math.js';

export const doAdd = (a, b) => add(a, b);
Enter fullscreen mode Exit fullscreen mode
  • Create a test file add.test.js and import all exports from the add.js file as math. This is so they can be accessible in a math object.
import * as math from './add';

test('adds numbers passed as argument', () => {
const sum = math.doAdd(1, 2);
expect(sum).toBe(3);
});

Enter fullscreen mode Exit fullscreen mode

In the code above, we assign the math.add function which adds the two parameters passed to it to the variable sum. We then use the expect method which gives us access to the toBe() matcher to assert that the result of the sum is 3.

Your test result should look like this after running the test file

Test Result

Snapshot Testing With Jest

Snapshot testing is used when you want to catch unexpected changes in your UI. It is a technique used when the output of a test is being compared against a previously captured snapshot of the expected result to ensure consistency. The test passes if the output of the function matches the previously captured snapshot, if it doesn't, the test fails. In the following steps, we'll see how snapshot tests work by testing a button component.

  • Create a component and name it button.js and copy the following code
export default function Button() {
    return(
        <button>
            Click Me
        </button>
    )
}
Enter fullscreen mode Exit fullscreen mode
  • Create a test file button.test.js and copy the following code.
import React from 'react';
import renderer from 'react-test-renderer';
import Button from './Button';

test('Button should match its snapshot', () => {
  const button = renderer.create(<Button />).toJSON();
  expect(button).toMatchSnapshot();
});

Enter fullscreen mode Exit fullscreen mode

In the code above:

  • We import the renderer method from the react-test-renderer library that we installed earlier. We then use the renderer.create method to render the component.

  • After rendering, the toJSON() method is called to create a plain JavaScript object that represents the component and its children which is then saved to the variable button.

  • We then use the expect and toMatchSnapshot functions to compare the button with a saved snapshot.

  • On testing the file, a __snapshot__ folder is automatically created where snapshots are stored for comparison. You can think of it as where your history of snapshots is stored.

Your test result should look like this after you run your test:

Test Result

If there are any changes later(after the first snapshot was taken), Jest will throw an error and ask if you want to update the snapshot.

As a codebase evolves, Snapshot tests are often used in conjunction with unit tests to ensure that the output of a function remains consistent over time.

Conclusion

In conclusion, we see that unit testing is a critical aspect of software development that helps to ensure the quality and reliability of our code. It is an efficient way to validate that individual units of code work as intended, reducing the chances of us pushing bugs to production. So far, we have learned about Jest, how we can mock a function with Jest, and how to test using snapshots. Jest has a lot of other features that were not mentioned here, be sure to get your hands dirty. With the right understanding and use of these tools, we can make our testing process more effective and save time.

Top comments (0)