| name | react19-test-patterns |
| description | Provides before/after patterns for migrating test files to React 19 compatibility, including act() imports, Simulate removal, and StrictMode call count changes. |
React 19 Test Migration Patterns
Reference for all test file migrations required by React 19.
Priority Order
Fix test files in this order; each layer depends on the previous:
act import fix first, it unblocks everything else
Simulate → fireEvent fix immediately after act
- Full react-dom/test-utils cleanup remove remaining imports
- StrictMode call counts measure actual, don't guess
- Async act wrapping for remaining "not wrapped in act" warnings
- Custom render helper verify once per codebase, not per test
1. act() Import Fix
import { act } from 'react-dom/test-utils';
import { act } from 'react';
If mixed with other test-utils imports:
import { act, Simulate, renderIntoDocument } from 'react-dom/test-utils';
import { act } from 'react';
import { fireEvent, render } from '@testing-library/react';
2. Simulate → fireEvent
import { Simulate } from 'react-dom/test-utils';
Simulate.click(element);
Simulate.change(input, { target: { value: 'hello' } });
Simulate.submit(form);
Simulate.keyDown(element, { key: 'Enter', keyCode: 13 });
import { fireEvent } from '@testing-library/react';
fireEvent.click(element);
fireEvent.change(input, { target: { value: 'hello' } });
fireEvent.submit(form);
fireEvent.keyDown(element, { key: 'Enter', keyCode: 13 });
3. react-dom/test-utils Full API Map
| Old (react-dom/test-utils) | New location |
|---|
act | import { act } from 'react' |
Simulate | fireEvent from @testing-library/react |
renderIntoDocument | render from @testing-library/react |
findRenderedDOMComponentWithTag | getByRole, getByTestId from RTL |
findRenderedDOMComponentWithClass | getByRole or container.querySelector |
scryRenderedDOMComponentsWithTag | getAllByRole from RTL |
isElement, isCompositeComponent | Remove not needed with RTL |
isDOMComponent | Remove |
4. StrictMode Call Count Fixes
React 19 StrictMode no longer double-invokes useEffect in development. Spy assertions counting effect calls must be updated.
Strategy always measure, never guess:
npm test -- --watchAll=false --testPathPattern="[filename]" --forceExit 2>&1 | grep -E "Expected|Received"
expect(mockFn).toHaveBeenCalledTimes(2);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(renderSpy).toHaveBeenCalledTimes(2);