测试未包含在 act(...)

Test was not wrapped in act(...)

我 运行 遇到了一个奇怪的问题,希望能得到帮助。我按照 here 中的示例进行操作,不知道到底发生了什么。警告应该不会出现吧?

组件:Hello.tsx

import React, { useEffect, useState } from "react"

export default () => {
  const [loaded, setLoaded] = useState("false")

  useEffect(() => {
    async function load() {
      await Promise.resolve()
      setLoaded("true")
    }
    load()
  }, [])

  return loaded ? <div>loaded</div> : <div>loading...</div>
}

测试:

import { render } from "@testing-library/react"
import Hello from "./hello"

test("React Testing Library works!", () => {
  render(<Hello />)
})

测试通过,但我在控制台中看到警告:

Warning: An update to _default 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
        at _default (/Users/michael.kozakov/Snapchat/Dev/web/apps/bitmoji-studio/src/ui/routes/Edit/Sidebar/hello.tsx:4:31)

       7 |     async function load() {
       8 |       await Promise.resolve()
    >  9 |       setLoaded("true")
         |       ^
      10 |     }
      11 |     load()
      12 |   }, [])

codesandbox中的测试样例通过,没有警告。您忘记使用 await screen.findByText(/loaded/i)findBy 查询:

findBy methods are a combination of getBy queries and waitFor

findBy queries work when you expect an element to appear but the change to the DOM might not happen immediately.

为了测试异步代码,您需要等待应用状态更新。所以你需要使用 waitForfindBy 查询。

findBy 查询在底层使用 waitFor,参见 makeFindQuery