Skip to main content
Testing React components ensures they work correctly and prevents regressions. This guide covers common testing patterns using React Testing Library and Jest.

Testing Philosophy

Test User Behavior

Test components the way users interact with them, not implementation details.

Avoid Testing Internals

Don’t test state variables or internal functions directly. Test the output.

Use Real DOM

React Testing Library uses real DOM nodes for more realistic tests.

Accessibility First

Query elements by accessible attributes like labels and roles.

Common Testing Patterns

Testing Asynchronous Updates

Many React components update asynchronously, especially when using libraries like React DnD or data fetching hooks. Here’s how to handle async updates:
If you see warnings about wrapping tests in act(...), it usually means:
  • The component updated after the test completed
  • There are pending async updates
  • You need to wait for updates to finish
The solution is to use waitFor() from React Testing Library.

Example: Testing a Drag and Drop Component

Here’s a real example of testing a component that updates asynchronously:
This test fails because the dragStart event doesn’t immediately update the component’s style. The collect function takes time to run.

Key Testing Concepts

Using waitFor()

waitFor() is essential for testing components that update asynchronously:
waitFor() repeatedly checks the assertion until it passes or times out. This is perfect for async updates.

Testing User Interactions

Test components by simulating user actions:

Testing Redux Connected Components

When testing components connected to Redux:

Testing Portals

Components that render to portals (like modals) need special handling:

Common Test Patterns

Testing Hooks

Test custom hooks using the renderHook utility:

Testing Forms

Test form submissions and validation:

Testing Error States

Test error handling and error boundaries:

Best Practices

Query Priority

Prefer queries in this order:
  1. getByRole
  2. getByLabelText
  3. getByPlaceholderText
  4. getByText
  5. getByTestId (last resort)

Async Utilities

Use waitFor, findBy*, and waitForElementToBeRemoved for async operations.

User Events

Prefer @testing-library/user-event over fireEvent for more realistic interactions.

Cleanup

React Testing Library automatically cleans up, but clean up mocks and timers manually.

Summary: Key Takeaways

1

Handle Async Updates

Use waitFor() when testing components that update asynchronously. This solves most act(...) warnings.
2

Test User Behavior

Focus on testing what users see and do, not implementation details.
3

Setup Test Environment

Ensure you have the latest testing library versions and proper test environment configuration.
4

Mock External Dependencies

Mock API calls, timers, and external libraries for reliable tests.
Common issues:
  • act(...) warnings usually mean async updates weren’t awaited
  • MutationObserver is not a constructor requires --env=jsdom-fourteen
  • Missing cleanup can cause test interference