testing-library / testing-library/react-testing-library

Receiving 'event was not wrapped in act' warning after upgrading to React 18

Open
#1,216 23 comments 15 reactions 0 assignees View on GitHub

@eps1lon is already working on this.

Since May 22, 2023.

  • #1214 by @eps1lon — open
bug
Dominant language
JavaScript
Stars
19.7k
Forks
1.2k
Avg merge
3d 16h
Merged PRs (30d)
1

Description

  • @testing-library/react version: 14.0.0
  • Testing Framework and version: jest
  • DOM Environment:
Relevant code or config:
// CompA.tsx

const CompA = () => null;
export default CompA;

// CompB.tsx

import { lazy } from "react";

const CompB = () => {
  const Example = lazy(() => import("./CompA"));

  return <Example />;
};

export default CompB;

// CompC.tsx

import CompB from './CompB';

const CompC = () => <CompB />;

export default CompC;

// CompC.test.tsx

import { render } from "@testing-library/react";
import CompC from './CompC';

// This test will throw `act()` warning even though CompC is not using `lazy` directly.
describe("CompC", () => {
  test(`Renders`, () => {
    expect(() => {
      render(<CompC />);
    }).not.toThrow();
  });
});
What you did:

Run test using yarn test from a CRA configured project.

What happened:

Receiving warning,

console.error
    Warning: A suspended resource finished loading inside a test, but the event was not wrapped in act(...).
    
    When testing, code that resolves suspended data should be wrapped into act(...):
    
    act(() => {
      /* finish loading suspended data */
    });
    /* 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
Reproduction:

Sandbox: https://codesandbox.io/p/sandbox/demo-act-warning-nested-1p4vjn?selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A1%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A1%7D%5D&file=%2Fsrc%2FCompC.test.tsx%3A7%2C25

Problem description:

act() warning started to appear after upgrading to React 18.

Wrapping with waitFor approach (as suggested here) has the following drawback.

Considering lazy is used on a shared component, we'll have to update all the tests for all the components that are using the shared component (even though those components are not using lazy directly). For a large codebase, we'll have to update tests for hundreds of components. Even if we have only one shared component using lazy, we'll have to update all the dependent component tests.

Seems like a lot of work!

Could we somehow keep the behavior identical to that on React 16 (act warning is not raised without needing waitFor)? It'll save a lot of developer effort.

Suggested solution:

No warning message

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the CompA.tsx, CompB.tsx, CompC.tsx, and CompC.test.tsx reproduction shown in the issue, then run yarn test in the CRA project or the linked CodeSandbox. Check how the nested React lazy component produces the React 18 act warning and compare the result with the requested no-warning behavior. The linked pull request may provide the current direction and should be reviewed before starting duplicate work.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react, typescript
Domain
frontend, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.