何时在带有 react-dom 的开玩笑单元测试中使用 act()

When to use act() in jest unit tests with react-dom

根据react单元测试文档:

act()

To prepare a component for assertions, wrap the code rendering it and performing updates inside an act() call. This makes your test run closer to how React works in the browser.

但测试在这两种情况下都运行良好:

没有act()

it('Should return some text', () => {
  render(<TestComponent />, container);
  expect(container.textContent).toBe('some text');
});

用act()

it('Should return some text', () => {
  act(() => {
    render(<TestComponent />, container);
  });

  expect(container.textContent).toBe('some text');
})

问题是:act() 到底做什么,什么时候应该使用它?

来自 act() 文档:

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. React provides a helper called act() that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions

进一步阅读和示例:https://github.com/mrdulin/react-act-examples/blob/master/sync.md

基本上,act() 是用来模拟 react 实际工作的。但是如果你使用来自 @testing-library/react 的 render,它会隐含地带有 act()。您可以在这里阅读更多相关信息:

https://es.reactjs.org/docs/testing-recipes.html#act

简单来说:

ReactTestUtilact() 确保任何可能需要时间的事情——渲染、用户事件、数据获取——在测试断言 运行 之前完成。

act(() => {
    // render components
    });
    // make assertions

如果您使用的是像 React Testing Library 这样的库,那么像 render 函数这样的东西 已经 包装在 act() 中,而且您通常不需要明确使用它。

请注意,React 测试库确实有它自己的 act() 函数,它只是 ReactTestUtilact() 的包装器。这在异步状态更新中可能很有用,尽管 waitFor 等其他 React 测试库工具可能更好。