| technology | React | |||||||
|---|---|---|---|---|---|---|---|---|
| domain | frontend | |||||||
| level | Senior/Architect | |||||||
| version | 19+ | |||||||
| tags |
|
|||||||
| ai_role | Senior React Testing Expert | |||||||
| last_updated | 2026-04-05 |
- Primary Goal: Enforce highly reliable, fast, and deterministic testing patterns in React.
- Target Tooling: Cursor, Windsurf, Antigravity.
- Tech Stack Version: React 19+
Important
Strict Constraints for AI:
- Always test user behavior, not implementation details.
- Never mock excessive internal state or standard React hooks; rely on integration testing methodologies.
Note
Context: Verifying component logic using tools like Enzyme or direct state inspection.
test('updates state on click', () => {
const wrapper = shallow(<Counter />);
wrapper.find('button').simulate('click');
expect(wrapper.state().count).toBe(1);
});Testing internal state makes tests brittle. If you refactor a class component to a functional component with hooks, the test will break even if the UI remains identical, leading to high maintenance overhead.
import { render, screen, fireEvent } from '@testing-library/react';
test('increments counter on click', () => {
render(<Counter />);
const button = screen.getByRole('button', { name: /increment/i });
fireEvent.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});Test from the user's perspective using React Testing Library. Query by accessible roles and verify the DOM output. This guarantees that refactoring implementation details will not break your test suite.
Note
Context: Testing components that fetch data or have delayed rendering.
test('loads data', () => {
render(<UserProfile id="1" />);
// Assuming the API call takes time, this assertion runs immediately and fails.
expect(screen.getByText('John Doe')).toBeInTheDocument();
});React components that perform async operations will throw "act" warnings and fail assertions if the test runner doesn't wait for the microtask queue to resolve and the DOM to update.
import { render, screen } from '@testing-library/react';
test('loads data', async () => {
render(<UserProfile id="1" />);
const userName = await screen.findByText('John Doe');
expect(userName).toBeInTheDocument();
});Use async utilities like findBy* or waitFor from React Testing Library. These tools inherently wrap updates in act() and poll the DOM until the asynchronous state resolves, ensuring deterministic test execution.