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:The act(...) Warning
The act(...) Warning
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
waitFor() from React Testing Library.Example: Testing a Drag and Drop Component
Here’s a real example of testing a component that updates asynchronously:- Problematic Test
- Fixed Test
- Setup Requirements
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:
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 therenderHook 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:
getByRolegetByLabelTextgetByPlaceholderTextgetByTextgetByTestId(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.