React Unit Testing with jest and enzyme

React Unit Testing with jest and enzyme

Jest

it is a framework that executes the test written in tests folder and .test.js suffix file. jest is like a container in which we write our tests and jest will help to execute those tasks.

Enzyme

it is a library that provides the interface to write the unit tests of components. there are mainly 3 methods to write the enzyme tests for components.

Shallow- The best method for the unit test of individual components.
This method includes the lifecycle method of components and render method. No child components are included,(UNIT TEST OF COMPONENT)

Mount- same as shallow but mounts with all children and parent/host component

Render- this method only includes static HTML including child components.

You can use any of these to test your components but at the start, you should only use shallow.

Some use cases

  1. If you want to test only a single component then use shallow.
  2. If you want to test component lifecycle and children's behavior, use mount.
  3. If you want to test children rendering with less overhead than mount and you are not interested in lifecycle methods, use render

Setting up Jest and enzyme in react testing-

  1. CRA comes bundled with jest. so no need to install jest.
  2. Install enzyme using the command npm install enzyme enzyme-adapter-react-17 enzyme-to-json --save-dev
  3. check if the yarn test command is working or not.
  4. if not working see your package.json config file and add the following changes-
"scripts": {
            "test": "jest"
          },
          "jest": {
            "verbose": true,
            "testPathIgnorePatterns": [
              "/node_modules/",
              "<rootDir>/config/webpack/test.js",
              "/vendor/"
            ]
          }
  1. create a setupTests.js file in the root folder and add the following code-
import { configure } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';

configure({ adapter: new Adapter() });

Example to write the unit test of a component -

Inside__tests__ folder create a new test file for register component register.test.js and add the following code-

import React from "react";
import {Register} from "../authentication/Register";
import "../../setupTests";

import { shallow } from "enzyme";

let wrapper;
beforeEach(() => {
  wrapper = shallow(<Register />);
});
describe("<Register/> rendering", () => {
  it("should render one <Form> ", () => {
    expect(wrapper.find("form")).toHaveLength(1);
  });

  it("should render 5 <input> ", () => {
    expect(wrapper.find("input")).toHaveLength(5);
  });
});

describe("<Register /> interactions", () => {
  it("should change state of email input", () => {
    wrapper
      .find('input[type="email"]')
      .simulate("change", {
        target: { name: "email", value: "someone@gmail.com" },
      });
    expect(wrapper.state("email")).toEqual("someone@gmail.com");
    expect(wrapper.state("password")).toEqual("");
  });

  it("should change state of password input", () => {
    wrapper
      .find('input[type="password"]')
      .first()
      .simulate("change", { target: { name: "password", value: "password" } });
    expect(wrapper.state("password")).toEqual("password");
    expect(wrapper.state("email")).toEqual("");
  });
});

Explanation of above code

Here I have used shallow to test for the individual component.

  1. beforeEach() method is called whenever a new test runs. for example before each of the describe() method beforeEach() will be called. this method is useful when you want to run multiple tests in a single component.

  2. describe() method (callback method) is used to run the test of similar type. suppose there are two tests related to rendering. then they should come in a single describe method. this is just a convention you can use multiple describe components for rendering too. but that will be meaningless.

  3. inside describe there are individual it() method which will test for something specific action.

  4. expect() is a method that is used to check for a certain assertion. for example: in the below method, it() expects the form length to be 1. which should be true. if the form length returned from the component is other than 1 then the test fails.

it("should render one <Form> ", () => {
    expect(wrapper.find("form")).toHaveLength(1);
  });

I hope you understand the basics of the react test. If there are any queries comment down below.