0
0
ReactHow-ToBeginner · 4 min read

How to Use userEvent in Testing Library with React

Use userEvent from @testing-library/user-event to simulate real user interactions in React tests. Import it, then call methods like click() or type() on elements to mimic user behavior.
📐

Syntax

The userEvent object provides methods to simulate user actions on DOM elements in React tests. You first import userEvent from @testing-library/user-event. Then you call methods like click(element), type(element, text), or clear(element) to mimic user input.

Each method takes the target element as the first argument. For typing, the second argument is the string to enter.

javascript
import userEvent from '@testing-library/user-event';

// Example usage:
await userEvent.click(buttonElement);
await userEvent.type(inputElement, 'Hello');
💻

Example

This example shows a simple React component with an input and a button. The test uses userEvent.type to enter text and userEvent.click to submit. It verifies the displayed output updates accordingly.

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

function Greeting() {
  const [name, setName] = useState('');
  const [greet, setGreet] = useState('');

  const handleClick = () => {
    setGreet(`Hello, ${name}!`);
  };

  return (
    <div>
      <input
        aria-label="name-input"
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={handleClick}>Greet</button>
      <p>{greet}</p>
    </div>
  );
}

// Test
test('userEvent types and clicks correctly', async () => {
  render(<Greeting />);

  const input = screen.getByLabelText('name-input');
  const button = screen.getByRole('button', { name: 'Greet' });

  await userEvent.type(input, 'Alice');
  await userEvent.click(button);

  expect(screen.getByText('Hello, Alice!')).toBeInTheDocument();
});
Output
Test passes with greeting text 'Hello, Alice!' displayed after typing and clicking.
⚠️

Common Pitfalls

  • Not awaiting userEvent.type can cause flaky tests because typing is async.
  • Using fireEvent instead of userEvent misses realistic user behavior like delays and events sequence.
  • For controlled inputs, ensure the component updates state on onChange to reflect typed text.
javascript
/* Wrong: missing await on userEvent.type */
userEvent.type(input, 'Bob');
userEvent.click(button);

/* Right: await userEvent.type to complete typing */
await userEvent.type(input, 'Bob');
await userEvent.click(button);
📊

Quick Reference

MethodDescriptionUsage Example
click(element)Simulates a mouse click on the elementawait userEvent.click(button)
type(element, text)Types text into an input or textarea asynchronouslyawait userEvent.type(input, 'Hello')
clear(element)Clears the value of an input or textareaawait userEvent.clear(input)
dblClick(element)Simulates a double clickawait userEvent.dblClick(button)
hover(element)Simulates mouse hoverawait userEvent.hover(div)
unhover(element)Simulates mouse leaving elementawait userEvent.unhover(div)

Key Takeaways

Import userEvent from '@testing-library/user-event' to simulate user actions in React tests.
Always await userEvent.type because it is asynchronous and mimics real typing delays.
Use userEvent methods like click and type to test user interactions realistically.
Avoid fireEvent for typing and clicking as userEvent better simulates real user behavior.
Ensure your React components update state on input changes to reflect userEvent typing.