React
Firing events
Learn to click and type with fireEvent and userEvent.
Triggering events
RTL offers two ways to trigger events: fireEvent dispatches low-level synthetic events; userEvent mimics real user behaviour (focus, keyboard, click) at a higher level.
Modern projects prefer userEvent because it follows real browser flow. For example, userEvent.click(btn) sets focus before clicking.
Use await for async operations; otherwise the assertion runs too early.
Awaiting async
If a click triggers an async update, the test must use await. Otherwise the assertion runs before the DOM updates and the test becomes flaky.
First set up the user: const user = userEvent.setup(); then call await user.click(btn). This pattern is React 18 compatible and safest.
To find text that appears later, findByText is also useful; it returns a Promise.
Exercise Click test
The Counter component increments on click. Write a test: set up a user with userEvent.setup(), render <Counter />, find the button via screen.getByRole('button'), call await user.click(btn), and assert with expect(screen.getByText(/Count: 1/)).toBeInTheDocument(). The test must be wrapped in test() and be async.
Show example solution
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { Counter } from "./Counter";
test("click increments", async () => {
const user = userEvent.setup();
render(<Counter />);
const btn = screen.getByRole("button");
await user.click(btn);
expect(screen.getByText(/Count: 1/)).toBeInTheDocument();
});
Test yourself
-
Which is closer to real user behaviour?
- fireEvent.click
- btn.dispatchEvent
- btn.click()
- userEvent.click
Show answer
userEvent.click — userEvent simulates focus and keyboard realistically.
-
userEvent.setup
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
render(<Counter />);
const user = userEvent.____();
Show answer
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
render(<Counter />);
const user = userEvent.setup();
-
Firing events: match the terms
- fireEvent
- Low level
- userEvent
- High level
- await
- Async
- findByText
- Returns Promise
Next lesson: Summary - RTL tests