Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render does not await act() #1385

Open
nstepien opened this issue Mar 8, 2025 · 1 comment
Open

render does not await act() #1385

nstepien opened this issue Mar 8, 2025 · 1 comment

Comments

@nstepien
Copy link

nstepien commented Mar 8, 2025

  • @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

@nstepien
Copy link
Author

nstepien commented Mar 9, 2025

I see that there's already a PR for it: #1214

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant