console.error
Warning: An update to Counter inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
Links for solution:
The warning appears because React Testing Library is detecting a state update (setCount
or setAmount
) outside of React's act
function, which ensures the DOM updates are reflected properly during testing. The @testing-library/user-event
methods like click
, type
, or tab
are asynchronous, so the state updates need to be awaited properly to avoid this warning.
Here’s how to fix your test suite to eliminate the warning:
-
Await Asynchronous Actions Ensure all
user
actions are awaited properly usingawait
, as you're already doing in most places. This allows React Testing Library to handle theact
wrapping for you. -
Ensure
act
Wrapping Theuser.setup()
and theawait
approach you're using should already work if your testing library is up-to-date. However, ensure you have the latest versions of@testing-library/react
and@testing-library/user-event
. -
Add Explicit
await
Where Necessary Some tests might not be fully awaiting the updates (e.g., DOM assertions might occur before the DOM has updated). This can trigger warnings.
Here’s your updated test suite:
import { render, screen } from '@testing-library/react';
import { Counter } from './Counter';
import user from '@testing-library/user-event';
describe('Counter', () => {
test('renders correctly', () => {
render(<Counter />);
const countElement = screen.getByRole('heading');
expect(countElement).toBeInTheDocument();
const incrementButton = screen.getByRole('button', { name: 'Increment' });
expect(incrementButton).toBeInTheDocument();
const amountInput = screen.getByRole('spinbutton');
expect(amountInput).toBeInTheDocument();
const setButton = screen.getByRole('button', { name: 'Set' });
expect(setButton).toBeInTheDocument();
});
test('renders a count of 0', () => {
render(<Counter />);
const countElement = screen.getByRole('heading');
expect(countElement).toHaveTextContent('0');
});
test('renders a count of 1 after clicking the increment button', async () => {
const userEvent = user.setup();
render(<Counter />);
const incrementButton = screen.getByRole('button', { name: 'Increment' });
await userEvent.click(incrementButton);
const countElement = screen.getByRole('heading');
expect(countElement).toHaveTextContent('1');
});
test('renders a count of 2 after clicking the increment button twice', async () => {
const userEvent = user.setup();
render(<Counter />);
const incrementButton = screen.getByRole('button', { name: 'Increment' });
await userEvent.click(incrementButton);
await userEvent.click(incrementButton);
const countElement = screen.getByRole('heading');
expect(countElement).toHaveTextContent('2');
});
test('renders a count of 10 after clicking the set button', async () => {
const userEvent = user.setup();
render(<Counter />);
const amountInput = screen.getByRole('spinbutton');
await userEvent.type(amountInput, '10');
expect(amountInput).toHaveValue(10);
const setButton = screen.getByRole('button', { name: 'Set' });
await userEvent.click(setButton);
const countElement = screen.getByRole('heading');
expect(countElement).toHaveTextContent('10');
});
test('elements are focused in the right order', async () => {
const userEvent = user.setup();
render(<Counter />);
const amountInput = screen.getByRole('spinbutton');
const setButton = screen.getByRole('button', { name: 'Set' });
const incrementButton = screen.getByRole('button', { name: 'Increment' });
await userEvent.tab();
expect(incrementButton).toHaveFocus();
await userEvent.tab();
expect(amountInput).toHaveFocus();
await userEvent.tab();
expect(setButton).toHaveFocus();
});
});
-
await userEvent.*
Calls: Ensured alluser
interactions (click
,type
,tab
) are awaited properly. -
Consistent
user.setup()
: Usedconst userEvent = user.setup()
for consistency and to isolate the user events per test. -
Version Check: Make sure you are using the latest versions of React Testing Library:
@testing-library/react
:^14.0.0
@testing-library/user-event
:^14.0.0
Run:
npm install @testing-library/react @testing-library/user-event --save-dev
These updates will resolve the act
warning and ensure your tests are fully aligned with React's expectations for state updates.