单元测试如何正确等待useSWR异步请求返回的数据后执行断言
useSWR组件异步单元测试的正确等待方案
你当前遇到的问题是断言执行早于useSWR异步数据返回,setTimeout硬等待是不推荐的方案,正确实现方式如下:
方案1:使用findBy*异步查询(优先推荐)
React Testing Library的findBy*系列查询是getBy*查询和waitFor的组合,天生支持等待异步渲染的元素,默认超时时间为1000ms,可自定义配置。
修改后的测试代码如下:
test("StyleOptionDetails contains correct style option number", async () => { renderWithMockSwr( <StyleOptionDetails {...mockIStyleOptionDetailsProps} /> ) // 等待目标元素渲染后再执行断言 expect(await screen.findByText(123)).toBeInTheDocument(); // 如果需要调整超时时间,可传入第二个参数,示例为最长等待2秒 // expect(await screen.findByText(123, { timeout: 2000 })).toBeInTheDocument(); });
方案2:使用waitFor包裹断言(适用于自定义等待逻辑场景)
如果需要等待多个条件或者有特殊的判断逻辑,可以用waitFor包裹断言代码,它会轮询执行内部逻辑直到断言通过或者超时。
示例代码如下:
test("StyleOptionDetails contains correct style option number", async () => { renderWithMockSwr( <StyleOptionDetails {...mockIStyleOptionDetailsProps} /> ) await waitFor(() => { expect(screen.getByText(123)).toBeInTheDocument(); }) });
额外优化建议
- 可以直接在
renderWithMockSwr中预设对应接口的返回数据,mock掉异步请求的等待过程,让测试直接拿到数据渲染,执行速度更快。 - 不要使用setTimeout硬等待:固定等待时间要么会拖慢测试整体执行速度,要么因为环境性能差异出现偶现的测试失败,稳定性极低。
内容的提问来源于stack exchange,提问作者DLO
相关产品推荐
相关产品推荐

