reactjs - 如何告诉 Jest/RTL 适当地等待非 UI 异步操作完成?
问题描述
更新
经过一番挖掘,似乎我的效果层(SheetEffects.clearAll
)中的间谍方法实际上并没有被嘲笑,这就是expect
失败的原因,所以这不是 RTL 的问题。
原帖
我不认为我在考虑这个问题,但是如果您不同意,请给出一个彻底和深思熟虑的答复。KCD 的react-testing-library
文档提供了在执行 Jest 之前异步等待 DOM 更新的示例expect
。我的问题与如果在类似的异步过程中没有UI 更新(这可能超出 RTL 的预期范围)有关怎么办?
鉴于:
it('should dispatch the correct action when clicked', async () => {
const { container } = renderWithReduxProvider(<ClearAllButton />, {}, true)
// spying on this and checking if it's been called in the `wait` block fails
// jest.spyOn(SheetEffects, 'clearAll')
// this works within `wait`, but I don't need/want to test this here
const spy = jest.spyOn(SheetApiV2, 'clearAll').mockReturnValue(Promise.resolve())
fireEvent.click(container.firstChild as HTMLElement)
// this works, but I'm fairly certain it's a race condition
// and I'm just getting lucky
await wait(() => expect(spy).toHaveBeenCalledTimes(1))
})
由于我已经对效果层进行了单元测试,我真的只想能够明确确认组件调度了正确的操作(通过mapDispatchToProps
)。还有其他副作用方法可以查看这是否已完成,但我想专门测试组件是否调度了正确的操作,而不是由于此操作而调用了 reducer,或者调用了效果。
NB该renderWithReduxProvider
函数使用我们的效果中间件创建一个 Redux 存储,并返回一个<Provider/>
包装的连接组件。另请注意,效果函数是异步的。
解决方案
我认为你这样做的方式是正确的,只是wait
为了调用方法。
但是,我认为我不同意这种说法
由于我已经对效果层进行了单元测试,我真的只想能够明确确认组件调度了正确的操作
在我看来,你应该测试副作用是否发生。你看,调用SheetEffects.clearAll
是一个实现细节。如果你决定重写你的应用程序而不使用 Redux 怎么办?或者如果你重命名clearAll
为clearEverything
? 换句话说,如果你重构代码会发生什么?测试将中断。
但是,如果您测试副作用,测试仍然有效,因为它不关心底层实现。该测试还将使您更有信心,因为您将测试完整功能是否有效。
另外,您可以摆脱单元测试,clearAll
因为您正在隐式测试它。
一点旁注:当你使用时,jest.spyOn
你应该在测试结束时重置你的间谍。你可以这样做spy.mockRestore()
推荐阅读
- android - 将逻辑从适配器移动到片段 - 错误:找不到视图 ID
- java - 来自另一个线程的 JDBC 连接阻止访问查询执行
- django - Django Channels - 连接到外部 Websocket
- docker - 在 jwilder/nginx-proxy 网络上隔离容器
- javascript - 图片 src 相对路径到绝对路径
- android - 使用深层链接从网站打开应用程序
- python - 为什么这个函数不能从多线程中受益?
- java - 无法为 org.gradle.api.Project 类型的项目“:app”获取未知属性“VERSION_CODE”
- php - 如何将命令参数发送到 php 文件
- python - Darkflow 说图像的尺寸为 0