Jest - Testing with React and React Testing Library: Useful APIs
Jen C.

Jen C. @jenchen

About: Front-End Engineer passionate about full-stack development

Joined:
Jun 4, 2023

Jest - Testing with React and React Testing Library: Useful APIs

Publish Date: May 21
11 5

Resources

react-testing-library API

Firing Events

waitFor

About Queries

Document: querySelector() method

render

Render into a container which is appended to document.body.

For example, render a component before each test and store the result in the renderResult variable:

describe('<Card />', () => {
  let renderResult = null;
  const props = {
    id: '1',
    title: 'test title',
    };

  beforeEach(() => {
    renderResult = render(<Card {...props} />);
    });

...

});
Enter fullscreen mode Exit fullscreen mode

Logging the HTML

If you want to see the actual HTML output of your component (as it would appear in the browser), you can log the innerHTML of the container from the renderResult like this:

console.log(renderResult.container.innerHTML);
Enter fullscreen mode Exit fullscreen mode

Output

<div class="card__info">
    <a class="card__txt-link" href="/video/1">
      <div class="card__top">
        <div class="card__title-wrapper">
          <h3 class="card__title">test title</h3>
        </div>
      </div>
    </a>
  </div>
Enter fullscreen mode Exit fullscreen mode

Get an element from the render result's container.

For example, use querySelector() to select the first matching element by CSS selector:

expect(
      contentRenderResult.container.querySelector('.detail-meta__studio')
        .textContent
    ).toBe(props.studio);
Enter fullscreen mode Exit fullscreen mode

rerender

Use when you need to update props, re-render the component, and verify the updated props are rendered correctly.

For example:

it('should render watermark if "watermark" prop is set', () => {
    const getWatermark = (container) =>
      container.querySelector('.card__watermark');
    const waterMarkUrl = '/static/images/logo-water.svg';

    let watermark = getWatermark(renderResult.container);
    expect(watermark).not.toBeInTheDocument();

    renderResult.rerender(
      <Card
        {...{
          ...props,
          watermark: {
            url: waterMarkUrl,
            alt: 'water',
          },
        }}
      />
    );
    watermark = getWatermark(renderResult.container);
    expect(watermark).toBeInTheDocument();
    expect(watermark.querySelector('img')).toHaveAttribute('src', waterMarkUrl);
  });
Enter fullscreen mode Exit fullscreen mode

User Actions

fireEvent

For example, simulate a click on an element and check that the onClickItem callback function is called:

const handleItemClick = jest.fn();

it('should trigger "onClickItem" prop when item is clicked', () => {
    fireEvent.click(screen.getByRole('menuitem'));
    expect(handleItemClick).toHaveBeenCalledTimes(1);
  });
Enter fullscreen mode Exit fullscreen mode

Note: Make sure handleItemClick is passed as the onClickItem prop to the component being tested. Otherwise, the callback won't be triggered.

waitFor

When you need to wait for something to either pass or fail.

For example, wait for the button to appear:

UserProfile.jsx

import { useEffect, useState } from 'react';

export default function UserProfile() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // Simulate network request
    setTimeout(() => {
      setUser({ name: 'Alice' });
    }, 500);
  }, []);

  return (
    <div>
      {user ? <button className="logout-button">Logout</button> : <p>Loading...</p>}
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

UserProfile.test.jsx

it('shows logout button after user is loaded', async () => {
  render(<UserProfile />);

  await waitFor(() => {
    expect(screen.getByText('Logout')).toBeInTheDocument();
  });
});
Enter fullscreen mode Exit fullscreen mode

Queries

screen

DOM Testing Library also exports a screen object which has every query that is pre-bound to document.body

For example, check that the heading renders correctly:

it('renders the title heading correctly', () => {
  expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(props.title);
});
Enter fullscreen mode Exit fullscreen mode

Comments 5 total

  • Dotallio
    DotallioMay 21, 2025

    Super useful overview, thanks for showing real examples! Do you have a favorite lesser-known trick for debugging with RTL?

  • Nevo David
    Nevo DavidMay 21, 2025

    Been needing a rundown like this for a minute, honestly makes me want to write some tests today.

    • Jen C.
      Jen C.May 21, 2025

      Thank you @nevodavid ! I just realized that I have starred the GitHub repo Novu a while ago. It's super cool :D

  • Nathan Tarbert
    Nathan TarbertMay 21, 2025

    Pretty cool, I always pick up something new digging through these kinds of details.

Add comment