React Testing Library

What is the React Testing Library?

Introduction

React Testing Library builds on top of DOM Testing Library.

It is a small testing library for React components.

It adds lightweight utility functions to react-dom and react-dom/test-utils, encouraging better testing techniques.

The following is its main guiding principle:

The closer your tests are to how your program is used, the more trust you’ll have in it.

Hire React js Developers

Install

Create React App projects provide support for the React Testing Library right out of the box.

If that isn’t the case, you can use npm to add it:

npm install –save-dev @testing-library/react

How does the react testing library work?

Instead of dealing with instances of rendered React components, your tests will deal with DOM elements.

The utilities provided by this package make it possible to query the DOM in the same way that a user would.

Finding form elements by their label text (like a user would), as well as links and buttons by their text (like a user would).

It also provides a recommended approach to discovering elements using a data-testid as an “escape hatch” for components with text content and labels that don’t make sense or aren’t practical.

An enzyme can be replaced by this library.

This library isn’t for you if you’re looking for:

  • A framework or test runner.
  • The library is specific to a testing framework (though it recommends Jest), but it works with any framework.

Methods for Finding Elements

Most of your React test cases should use methods for finding elements.

It provides you with several methods to find an element by specific attributes in addition to the getByText() method above:

  • getByText(): find the element by its textContent value
  • getByRole(): by its role attribute value
  • getByLabelText(): by its label attribute value
  • getByPlaceholderText(): by its placeholder attribute value
  • getByAltText(): by its alt attribute value
  • getByDisplayValue(): by its value attribute, usually for <input> elements
  • getByTitle(): by its title attribute value

These methods are for getBy.

There are many other methods like findBy, queryBy, and getAllBy.

As we have these functions used in our for instance.

Example

Header.js

import React from 'react'
import "./Header.css"

export default function Header({
  title
 }) 
{
  return (
    <>
        <h1 className="header" data-testid="header-1">{title}</h1>
    </>
  )
}

Header.test.js

import { render, screen } from '@testing-library/react';
import Header from "../Header";

describe("Header", () => {
  it('should render same text passed into title prop', async () => {
    render(<Header title="My Header" />);
    const headingElement = screen.getByText(/my header/i);
    expect(headingElement).toBeInTheDocument();
  });
})

it('should render same text passed into title prop', async () => {
  render(<Header title="My Header"/>);
  const headingElement = screen.getByRole("heading");
  expect(headingElement).toBeInTheDocument(); 
});

it('should render same text passed into title prop', async () => {
  render(<Header title="My Header" />);
  const headingElement = screen.getByRole("heading", { name: "My Header" });
  expect(headingElement).toBeInTheDocument();
});

it('should render same text passed into title prop', async () => {
  render(<Header title="My Header" />);
  const headingElement = screen.getByTitle("Header");
  expect(headingElement).toBeInTheDocument();
});

it('should render same text passed into title prop', async () => {
  render(<Header title="My Header" />);
  const headingElement = screen.getByTestId("header-1");
  expect(headingElement).toBeInTheDocument();
});

//Find By

it('should render same text passed into title prop', async () => {
  render(<Header title="My Header" />);
  const headingElement = await screen.findByText(/my header/i);
  expect(headingElement).toBeInTheDocument();
});

//QueryBy

it('should render same text passed into title prop', async () => {
  render(<Header title="My Header" />);
  const headingElement = screen.queryByText(/dogs/i);
  expect(headingElement).not.toBeInTheDocument();
});

Mocking function:

AddInput.js

import React, { useState } from 'react'
import "./AddInput.css"
import { v4 } from "uuid"

function AddInput({ setTodos, todos}) {

const [todo, setTodo] = useState("")

const addTodo = () => {
  let updatedTodos = [
    ...todos,
    {
      id: v4(),
      task: todo,
      completed: false
    }
  ]
  setTodos(updatedTodos);
  setTodo("")
}

return (
  <div className="input-container">
    <input
      className="input"
      value={todo}
      onChange={(e) => setTodo(e.target.value)}
      placeholder="Add a new task here..."
    />
    <button
      className="add-btn"
      onClick={addTodo}
    >
      Add
     </button>
   </div>
  )
}

export default AddInput

AddInput.test.js

import { render, screen, fireEvent } from '@testing-library/react';
import AddInput from "../AddInput";

const mockedSetTodo=jest.fn();

describe("AddInput", () => {
  it('should render input element', async () => {
    render(
      <AddInput
        todos={[]}
        setTodos={mockedSetTodo}
      />
    );
    const inputElement = screen.getByPlaceholderText(/Add a new task here.../i);
    expect(inputElement).toBeInTheDocument();
  });

it('should be able to type into input', async () => {
  render(
    <AddInput
      todos={[]}
      setTodos={mockedSetTodo}
    />
  );
  const inputElement = screen.getByPlaceholderText(/Add a new task here.../i);
  fireEvent.change(inputElement, { target: { value: "Go Grocery Shopping" } });
  expect(inputElement.value).toBe("Go Grocery Shopping");
  });

})

In conclusion, here is a similar reference link for React Testing Library

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.