What is the React Testing Library?
Introduction
React Testing Library builds on top of the 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.
Install
Creating 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
Leave a Reply
Want to join the discussion?Feel free to contribute!