0
0
ReactHow-ToBeginner · 4 min read

How to Test Click Event in React Using React Testing Library

To test a click event in React, use React Testing Library's fireEvent.click or userEvent.click on the target element and then check the expected outcome. This simulates a user clicking and lets you verify component behavior in tests.
📐

Syntax

Use fireEvent.click(element) or userEvent.click(element) to simulate a click on a React element in your test. Then use assertions to check if the click caused the expected changes.

  • element: The DOM node you want to click.
  • fireEvent: A utility from React Testing Library to simulate events.
  • userEvent: A more user-like event simulation library recommended for better realism.
javascript
import { render, screen, fireEvent } from '@testing-library/react';

// Simulate click
fireEvent.click(element);

// Or with userEvent (preferred)
import userEvent from '@testing-library/user-event';

const user = userEvent.setup();
await user.click(element);
💻

Example

This example shows a button that increments a counter when clicked. The test renders the component, clicks the button, and checks if the counter updates.

javascript
import React, { useState } from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

// Test
test('increments counter on click', async () => {
  render(<Counter />);
  const button = screen.getByRole('button', { name: /increment/i });
  const user = userEvent.setup();

  expect(screen.getByText(/count: 0/i)).toBeInTheDocument();

  await user.click(button);

  expect(screen.getByText(/count: 1/i)).toBeInTheDocument();
});
Output
Test passes if the counter text updates from 'Count: 0' to 'Count: 1' after clicking the button.
⚠️

Common Pitfalls

Common mistakes when testing click events include:

  • Not waiting for async updates when using userEvent, causing false negatives.
  • Using fireEvent instead of userEvent, which may not simulate real user behavior fully.
  • Querying elements incorrectly, e.g., using getByText for buttons instead of getByRole which is more accessible and reliable.
javascript
/* Wrong way: Using fireEvent without async handling */
fireEvent.click(button);
expect(screen.getByText(/count: 1/i)).toBeInTheDocument(); // May fail if update is async

/* Right way: Using userEvent with async */
const user = userEvent.setup();
await user.click(button);
expect(screen.getByText(/count: 1/i)).toBeInTheDocument();
📊

Quick Reference

FunctionPurposeNotes
fireEvent.click(element)Simulates a click eventBasic event simulation, less realistic
userEvent.click(element)Simulates user clickingPreferred for realistic user interaction, supports async
screen.getByRole('button', { name })Finds button by role and labelBest practice for accessibility
expect(...).toBeInTheDocument()Checks element presenceCommon assertion after click

Key Takeaways

Use React Testing Library's userEvent.click to simulate realistic click events.
Always query elements by role and accessible name for reliable tests.
Await userEvent.click when testing async updates to avoid flaky tests.
Check the UI changes after the click to confirm expected behavior.
Avoid fireEvent for complex user interactions; prefer userEvent for better simulation.