我应该如何测试只能在使用 @testing-library/react 的异步方法的生命周期内访问的功能?
How should I test functionality accessible only during the lifetime of an async method using @testing-library/react?
我有一个 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 中重现了这个问题(一定要选择右侧的 "Tests" 选项卡,然后查看右下角的 "Console" 消息)。
关于 this GitHub 问题的最后评论说,只要我使用 React 测试库助手和函数,我就不需要担心 act()
(我是)。我错过了什么?
针对 react-testing-library 提出问题 (here) 帮助我得出结论,最好的方法似乎是不要太担心它。该库的作者非常友好地提出了一种更简单的测试模式,即在导致组件进入您要测试的瞬态状态的操作之后直接进行断言。例如:
fireEvent.click(getByText("Submit")); // <-- action which triggers an async API call
expect(getByText("Fetching answers")).toBeInTheDocument();
以前,我在点击触发的 API 调用的模拟实现中有相同的 expect 语句。我的理由是,这是我可以确定断言 运行 当组件处于我试图测试的瞬态状态时的唯一方法。
AFAICT,这些测试对于异步操作并不严格正确,因为模拟实现返回的承诺 可能 在检查预期之前解决。但在实践中,我观察到测试重写为更简单的方法:
- 不要在 OP 中引发有关重叠 act() 调用的警告
- 如果我更改非测试代码以破坏测试下的行为,则可以按预期失败
- 到目前为止还没有出现任何间歇性故障
- 更容易阅读和理解
这个问题从来没有引起太多关注,但我希望记录下我最终得出的答案,以便将来帮助其他人。
我有一个 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 中重现了这个问题(一定要选择右侧的 "Tests" 选项卡,然后查看右下角的 "Console" 消息)。
关于 this GitHub 问题的最后评论说,只要我使用 React 测试库助手和函数,我就不需要担心 act()
(我是)。我错过了什么?
针对 react-testing-library 提出问题 (here) 帮助我得出结论,最好的方法似乎是不要太担心它。该库的作者非常友好地提出了一种更简单的测试模式,即在导致组件进入您要测试的瞬态状态的操作之后直接进行断言。例如:
fireEvent.click(getByText("Submit")); // <-- action which triggers an async API call
expect(getByText("Fetching answers")).toBeInTheDocument();
以前,我在点击触发的 API 调用的模拟实现中有相同的 expect 语句。我的理由是,这是我可以确定断言 运行 当组件处于我试图测试的瞬态状态时的唯一方法。
AFAICT,这些测试对于异步操作并不严格正确,因为模拟实现返回的承诺 可能 在检查预期之前解决。但在实践中,我观察到测试重写为更简单的方法:
- 不要在 OP 中引发有关重叠 act() 调用的警告
- 如果我更改非测试代码以破坏测试下的行为,则可以按预期失败
- 到目前为止还没有出现任何间歇性故障
- 更容易阅读和理解
这个问题从来没有引起太多关注,但我希望记录下我最终得出的答案,以便将来帮助其他人。