-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
@nstepien
Description
@testing-library/react
version: 16.2.0- Testing Framework and version: vitest
- DOM Environment: chromium, via
@vitest/browser
Relevant code or config:
import { use } from 'react'; import { render, screen } from '@testing-library/react'; function TestComponent({ promise }: { promise: Promise<unknown> }) { use(promise); return 'test'; } test('render', async () => { const promise = new Promise((resolve) => { setTimeout(resolve, 10); }); render(<TestComponent promise={promise} />); await expect(screen.findByText('test')).resolves.toBeInTheDocument(); });
What you did:
I use use(promise)
in components.
What happened:
I get the following error when rendering via @testing-library/react
's render()
.
A component suspended inside an `act` scope, but the `act` call was not awaited. When testing React components that depend on asynchronous data, you must await the result:
await act(() => ...)
The test also fails:
Caused by: TestingLibraryElementError: Unable to find an element with the text: test. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
Reproduction:
See "Relevant code or config" above.
Adding an un-awaited act
manually does not resolve the issue either:
import { use } from 'react'; import { act, render, screen } from '@testing-library/react'; function TestComponent({ promise }: { promise: Promise<unknown> }) { use(promise); return 'test'; } test('render', async () => { const promise = new Promise((resolve) => { setTimeout(resolve, 10); }); act(() => { render(<TestComponent promise={promise} />); }); await expect(screen.findByText('test')).resolves.toBeInTheDocument(); });
Problem description:
I should never get any act warnings when using @testing-library/react
functions.
Suggested solution:
As the warning explicitly advises, awaiting the act
call fixes the warning/test:
import { use } from 'react'; import { act, render, screen } from '@testing-library/react'; function TestComponent({ promise }: { promise: Promise<unknown> }) { use(promise); return 'test'; } test('render', async () => { const promise = new Promise((resolve) => { setTimeout(resolve, 10); }); await act(() => { render(<TestComponent promise={promise} />); }); await expect(screen.findByText('test')).resolves.toBeInTheDocument(); });
AFAICT, in React 19, act
always returns a promise, so it may be best to always await
it.
Fixing the issue would make render
async, which may be a breaking change.
https://github.com/testing-library/react-testing-library/blob/main/src/pure.js#L149
Metadata
Metadata
Assignees
Labels
No labels