🔥
React Testing Library Explain
Table of contents
React Testing Library (RTL) is alternative to Airbnb's Enzyme.
Confusions
JEST VS REACT TESTING LIBRARY
React beginners often confuse the tools for testing in React. React Testing Library is not an alternative to Jest, because they need each other and every one of them has a clear task.
Code Examples
Selecting Elements
jsx
import React from "react";import { render, screen } from "@testing-library/react";import App from "./App";describe("App", () => {test("renders App component", () => {render(<App />);// implicit assertion// because getByText would throw error// if element wouldn't be therescreen.getByText("Search:");// explicit assertion// recommendedexpect(screen.getByText("Search:")).toBeInTheDocument();});});
Search Elements
jsx
// componentfunction getUser() {return Promise.resolve({ id: "1", name: "Robin" });}function App() {const [search, setSearch] = React.useState("");const [user, setUser] = React.useState(null);React.useEffect(() => {const loadUser = async () => {const user = await getUser();setUser(user);};loadUser();}, []);function handleChange(event) {setSearch(event.target.value);}return (<div>{user ? <p>Signed in as {user.name}</p> : null}<Search value={search} onChange={handleChange}>Search:</Search><p>Searches for {search ? search : "..."}</p></div>);}
jsx
import React from "react";import { render, screen } from "@testing-library/react";import App from "./App";describe("App", () => {test("renders App component", async () => {render(<App />);expect(screen.queryByText(/Signed in as/)).toBeNull();expect(await screen.findByText(/Signed in as/)).toBeInTheDocument();});});
Callback Handlers
jsx
describe("Search", () => {test("calls the onChange callback handler", async () => {const onChange = jest.fn();render(<Search value="" onChange={onChange}>Search:</Search>);await userEvent.type(screen.getByRole("textbox"), "JavaScript");expect(onChange).toHaveBeenCalledTimes(10);});});
Async
jsx
import React from 'react';import axios from 'axios';import { render, screen, act } from '@testing-library/react';import userEvent from '@testing-library/user-event';import App from './App';jest.mock('axios');describe('App', () => {test('fetches stories from an API and displays them', async () => {const stories = [{ objectID: '1', title: 'Hello' },{ objectID: '2', title: 'React' },];const promise = Promise.resolve({ data: { hits: stories } });axios.get.mockImplementationOnce(() => promise);render(<App />);await userEvent.click(screen.getByRole('button'));await act(() => promise);expect(screen.getAllByRole('listitem')).toHaveLength(2);});test('fetches stories from an API and fails', async () => {...});});