7

我有一个 React 组件,它允许用户向远程服务提交可能长时间运行的查询。当查询运行时,组件会显示一个取消按钮。我想测试这个按钮是否在预期的时候出现,它的点击处理程序取消了之前的 API 请求,等等。

由于按钮仅在异步 API 调用处于活动状态时出现,因此我为此目的编写的测试在异步 API 本身的模拟实现中对按钮进行断言。它们不是超级优雅,但我确认当我删除部分生产代码时它们确实会变红。

在将 @testing-library/react 从 8.0.1 升级到 9.3.2 时,虽然测试仍然通过,但我现在多次收到以下警告:

console.error node_modules/@testing-library/react/dist/act-compat.js:52
      Warning: You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one.

我在下面的 CodeSandbox 中重现了这个问题(请务必选择右侧的“测试”选项卡,然后查看右下角的“控制台”消息)。

编辑 sweet-clarke-kq299

关于这个GitHub 问题的最后评论说,act()只要我使用 React 测试库帮助程序和函数(我就是这样),我就不必担心。我错过了什么?

4

1 回答 1

7

针对 react-testing-library提出问题(此处)帮助我得出结论,最好的方法似乎是不要太担心它。该库的作者非常友好地提出了一种更简单的测试模式,即在导致组件进入您尝试测试的瞬态状态的操作之后直接进行断言。例如:

fireEvent.click(getByText("Submit")); // <-- action which triggers an async API call

expect(getByText("Fetching answers")).toBeInTheDocument();

以前,在单击触发的 API 调用的模拟实现中,我有相同的期望语句。我的理由是,这是我可以确定断言会在组件处于我试图测试的瞬态状态时运行的唯一方法。

AFAICT,这些测试对于异步操作并不严格正确,因为模拟实现返回的承诺可以在检查期望之前解决。但在实践中,我观察到测试重写为更简单的方法:

  • 不要在 OP 中引发关于重叠 act() 调用的警告
  • 如果我更改非测试代码以破坏被测行为,则可以按预期失败
  • 到目前为止还没有出现任何间歇性故障
  • 更容易阅读和理解

这个问题从来没有引起太多关注,但我希望记录我最终得到的答案可能会帮助其他人。

于 2020-05-27T14:00:32.537 回答