React Test Utilities

Gunjeev Singh
Last Updated: May 13, 2022

Introduction

Building fully functional React applications is in itself a big task, but making them ready for production and usage is another task in itself. Testing is an essential part of the development process. Without proper testing, we cannot judge the production quality of any application, and it may often give us undesirable results. Testing can become a difficult task, but various testing frameworks and libraries make testing React components easy. React offers us Test Utilities or utils in those frameworks, which make our testing process easier and more efficient.

Understanding the Testing Process

Before we dive into React Test Utilities, let us first look into the different components of any testing procedure. Testing React components is a three-part procedure. Testing ReactJs components consist of Arranging, Acting, and Asserting.  

 

Testing Process

 

Arranging means keeping your component ready in its original state. Acting refers to the action that happens with the element, including clicking, hovering, input, etc. Asserting is the part where we create a hypothesis as to how the state of our component would look once the user has performed the event. If our hypothesis matched the results, the tests would pass and fail under other circumstances. 

 

Unlike our React application, the tests are not performed in the browser. Instead, they are performed in dedicated testing environments. 


Now that we have understood the testing process, it is evident that React's testing utilities would also be somewhat parallel to this three-stage process. Let us look into them in detail.

 

Jest is a testing framework built-in and built for Javascript. It ensures the correctness of a Javascript codebase. Jest is also developed by the Facebook team, which is why testing React applications with Jest is a very common practice.  

React Test Utilities

Since the first part of the testing process is to make a component available for testing, let us see how that can be done using the react test utilities. 

act()

React, in its set of React test utilities, offers us the act() method. The act() method from the test utilities pack makes the component ready for testing. In simple terms, we wrap our component's code in an act() block so that the tests we make on the component are closer to how React works in the browser. 

As an example, let us look at the code below. The code below has a class-based react component that displays the number of times a user has clicked on a button.

Filename: App.test.js

class Count extends React.Component {
  constructor(props) {
    super(props);
    this.state = {num: 0};
    this.handleClick = this.handleClick.bind(this);
  }


  componentDidMount() {
    document.title = `You have clicked this ${this.state.num} times`;
  }


  componentDidUpdate() {
    document.title = `You have clicked this ${this.state.num} times`;
  }


  handleClick() {
    this.setState(state => ({
      num: state.num + 1,
    }));
  }


  render() {
    return (
      <div>
        <p>You have clicked this {this.state.num} times</p>
        <button onClick={this.handleClick}>
          Click here!
        </button>
      </div>
    );
  }
}

We would make the following changes to the code to test this component using React's test utilities.

Filename: App.test.js

import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
import Count from './Count';


let container;


beforeEach(() => {
  container = document.createElement('div');
  document.body.appendChild(container);
});


afterEach(() => {
  document.body.removeChild(container);
  container = null;
});


// The ‘it’ keyword is used to describe the test
it('can render and update a counter', () => { 
  // This part tests the first render and componentDidMount
  act(() => {    ReactDOM.render(<Count />, container);  }); 
  const button = container.querySelector('button');
  const label = container.querySelector('p');
 // The expect keyword is the assertion part of the testing process.
  expect(label.textContent).toBe('You have clicked 0 times');   expect(document.title).toBe('You have clicked 0 times');


  // This tests the second render and componentDidUpdate
  act(() => {    
button.dispatchEvent(new MouseEvent('click', {bubbles: true}));  });  expect(label.textContent).toBe('You have just clicked 1 times');
  expect(document.title).toBe('You have just clicked 1 times');
});

Below is a list of some of the most commonly used methods from the React Test Utilities library. 

isElement()

This checks if a given element is a react component. Returns true if yes, false if not.

isElement(element)

isElementOfType()

Returns true if a given element is a react component of type componentClass.

isElementOfType(
  element,
  componentClass
)

isDOMComponent()

This is again a boolean-type return statement. It returns true if the given instance is a DOM() Component. A DOM component is anything rendered on the DOM, such as a <div> or a <span>.

isDOMComponent(instance)

isCompositeComponent()

Again a boolean-type return statement, this method returns true if a given component is user-defined, such as a class or a function.

isCompositeComponent(instance)

A variation of this method is the isCompositeComponentOfType() method. 

findAllInRenderedTree()

This method runs through an entire tree and finds all components which return true on the specified test. Though this method is not very useful on its own, it becomes beneficial when used together with other methods.

findAllInRenderedTree(
  Example tree,
  Specific test
)

scryRendered and findRendered

There are two types of methods in the React Test Utilities. scryRendered and findRendered work the same way in all their variations except that findRendered expects only one object to satisfy the given condition. 

DOMComponentWithClass

This checks all DOM components with a specific class inside a tree.

  • scryDOMComponentWithClass()
scryRenderedDOMComponentsWithClass(
  tree,
  className
)
  • findDOMComponentWithClass()
findRenderedDOMComponentsWithClass(
  tree,
  className
)

 

RenderedComponentWithType()

This finds all instances of a component that match with the given class.

  • scryRenderedComponentWithClass()
scryRenderedComponentsWithType(
  tree,
  componentClass
)
  • findRenderedComponentWithClass()
findRenderedComponentsWithType(
  tree,
  componentClass
)

Other Methods

Method

Description

isCompositeComponentWithType()Returns a true response if the instance is a component with a given class.
scryRenderedDOMComponentsWithTag()Takes a tag name parameter and returns all those components on the DOM that match the tag name.
findRenderedDOMComponentWithTag()Takes a tag name parameter and returns all those components on the DOM that match the tag name but expects that there is just one result.

Frequently Asked Questions

1. What is the simulate() utility?
We can simulate any event dispatch on a sample DOM node using this. Simulate has a method for every react event. This includes click events, inputs, and other DOM events that react understands.

 

2. What is Jest?
Jest is a Javascript testing framework. It is designed and maintained by Facebook Inc., which is also the maintainer of React.

 

3. Which are the two ways to test components in React?
The two ways to test components in React is either by rendering them in trees in a testing environment and asserting the state or by actually rendering them in a browser.

 

4. What is Enzyme?
Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output.

Key Takeaways

This blog explained the various concepts that encapsulate the testing mechanism of any React application using the React Test Utilities. Now that you know how to test React applications using the Test Utilities, you are ready to create production-level applications. 

 

Now that you have completed your React Journey move on to the next step in MERN stack development with NodeJS. Refer to this link for a collection of NodeJS blogs.

Was this article helpful ?
1 upvote