Introduction to the Testing Library - coursehero/ch-react-workshop GitHub Wiki

What is the Testing Library

The @testing-library family of packages helps you test UI components in a user-centric way.

The more your tests resemble the way your software is used, the more confidence they can give you.

--- from https://testing-library.com/docs/ and https://kentcdodds.com/about/

Testing Library Frameworks

The Testing Library comes in many flavors. The following three are relevant for our workshop:

DOM Testing Library

  • provides utilities for querying the DOM the same way a user would: getBy*, getAllBy*, queryBy*, queryAllBy*, findBy*, findAllBy*
💡 Tip: use the Testing Playground to help debug your HTML for accessibility and to select the best query.

React Testing Library

  • adds API on top of DOM Testing Library: render, cleanup, act

Cypress Testing Library

  • adds the familiar API to the cy. command of Cypress

Simple React component

Let's assume you want to test the following React component:

import * as React from 'react'

const USERS = [
 { name: 'User 1', city: 'Tokyo' },
 { name: 'User 2', city: 'Prague' },
]

export const Users = () => {
  return (
    <ul>
      {USERS.map(({ name, city }: any) => (
        <li key={name}>
          {name} - {city}
        </li>
      ))}
    </ul>
  )
}

Here is what it would render:

  <ul>
    <li>User 1 - Tokyo</li>
    <li>User 2 - Prague</li>
  </ul>

Thinking about testing

A simple small or unit test using RTL

Try to write the test yourself!
import * as React from 'react'
import { render } from '@testing-library/react'
import { Users } from './Users'

test('Renders a list with the correct number of users', () => {
  const { getByRole } = render(<Users />)
  const usersList = getByRole('list')

  expect(usersList.children).toHaveLength(2)
})

Check for accessibility violations:

import { axe, toHaveNoViolations } from 'jest-axe'
import 'jest-axe/extend-expect'

...
const { container } = render(<Users />)
const results = await axe(container)
expect(results).toHaveNoViolations() // or expect(results.violations).toHaveLength(0)

Mocking API requests

Mosts components will be more complicated and some will render data coming from API endpoints. Here is an example of mocking the data:

import {loadGreeting as mockLoadGreeting} from '../api'


test('loads greetings on click', () => {
  mockLoadGreeting.mockResolvedValueOnce({data: {greeting: 'TEST_GREETING'}})
  const {getByLabelText, getByText} = render(<GreetingLoader />)
  const nameInput = getByLabelText(/name/i)
  const loadButton = getByText(/load/i)
  nameInput.value = 'Mary'
  fireEvent.click(loadButton)
})
💡 Tip: while you can always use the basic mocking or stubbing functionality provided by jest, we recommend a more sophisticated approach to mocking described in our Guide to Mocking.

Other related topics

Next steps

⚠️ **GitHub.com Fallback** ⚠️