2021-06-09 React Test 中 act() 有什么作用?


可能 Frontend 门槛真的太低了。竟然有自称熟练掌握 React 的人回答不上来 React Test act() 的用途。

如果你在工作中使用 React,那么迟早你会遇到如下的测试代码。

it("renders hello world", () => {
  act(() => {
    render(<HelloWorld />, container);
  });
  expect(container.textContent).toBe("Hello, World.");
});

但是绝大多数时候,你的测试代码是这样的:

it("renders hello world", () => {
  render(<HelloWorld />, container);
  expect(container.textContent).toBe("Hello, World.");
});

act() 有什么作用呢?为什么有的时候需要,有的时候却不需要呢?

React Docs

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. react-dom/test-utils 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:

TL;DR

很多时候,用户界面(UI)并不能一瞬间就被绘制完成,可能导致断言失败。act() 可以确保断言执行时 UI 已经被绘制完成。

act() 效果

no act

act render

那么是不是在所有测试中都应该写 act()?

理论上,写了绝对不会错,不写可能会出错。

不过不用担心,React 社区非常强大,已经有 open source 帮我们完成了这项枯燥乏味的工作。

Thanks testing-library

All renders and events being fired are wrapped in act, so you don't really need this.

我在面试中会如何提问 ?

  1. 你在项目中写测试吗?
  2. 如果 UI 存在异步或者耗时的操作,应该如何测试?
  3. 你了解 React test-utils act() 吗?
  4. 你能简单讲讲 act() 的原理吗?

refs: