How to unit test state of the component using jest and enzyme

Testing the state of the component is very simple. Lets take an example of below component with a state variable in React.

import React, { Component } from "react";
class Normal extends Component {
  constructor() {
    super();
    this.state = {
      index: 0
    };
    this.incrementIndex = this.incrementIndex.bind(this);
  }
  incrementIndex() {
    this.setState({
      index: this.state.index + 1
    });
  }
  render() {
    return (
      <div>
        <span id="index" data-testid="normal-index">
          {this.state.index}
        </span>
        <button onClick={this.incrementIndex}>Increment Index</button>
      </div>
    );
  }
}
export default Normal;

In the above component, we are using the state variable "index". When the button is clicked, the state variable is updated. We can unit test following things in this component using enzyme.

  • The initial state of the variable "index"
  • Funtionality of button click and change of state variable
  • Display of state variable "index"

Lets see the unit test code written in enzyme for the above component

import React from "react";
import { shallow } from "enzyme";
import _ from "lodash";
import Normal from "../Normal";

describe("Normal Tests", () => {
  it("should initialize index to 0", () => {
    // check for initial state
    const app = shallow(<Normal />);
    expect(app.state("index")).toEqual(0);
  });
  it("should call increment index on click of button", () => {
    const app = shallow(<Normal />);
    const spy = jest.spyOn(app.instance(), "incrementIndex");
    app.instance().forceUpdate();
    // force click and check for update
    app.find("button").simulate("click");
    expect(spy).toHaveBeenCalled();
  });
  it("should increment index - function test", () => {
    const app = shallow(<Normal />);
    expect(app.state("index")).toEqual(0);
    app.instance().incrementIndex();
    expect(app.state("index")).toEqual(1);
  });
  it("should increment index - button test", () => {
    const app = shallow(<Normal />);
    expect(app.state("index")).toEqual(0);
    app.find("button").simulate("click");
    expect(app.state("index")).toEqual(1);
  });
  it("it should display incremented index on click of button", () => {
    const app = shallow(<Normal />);
    app.find("button").simulate("click");
    expect(app.find("span#index").text()).toEqual("1");
  });
});

Conclusion

Following key points are to be noted in the above unit test code

  • We are using enzyme to unit test the component.
  • State of the component can be accessed using code app.state('index'), where app is the shallow rendered component.
  • The instance methods can be spyed upon using the code jest.spyOn(app.instance(), 'incrementIndex'), where incrementIndex is the instance method.
  • The UI elements inside the component can be accessed and clicked using the method app.find('button').simulate('click').