使用storybook-addon-specifications时setTimeout下测试状态未更新问题
解决storybook-addon-specifications中setTimeout断言不更新测试状态的问题
这个问题我之前帮人排查过,核心原因是测试框架没等到你的异步断言执行就结束了测试流程——当it块里的代码执行完(也就是调度了setTimeout之后),测试就默认完成了,之后setTimeout里的断言才跑,但测试框架已经不会再捕获这个结果了,所以Specifications标签里看不到更新的状态。
给你几个可行的解决办法:
1. 使用测试框架的done回调标记异步完成
Jest(storybook-addon-specifications通常基于Jest)支持通过done参数来告诉测试框架:“等我调用这个函数再结束测试”。修改你的代码如下:
it('Get Cookie', (done) => { setTimeout(() => { expect(mobstore.loginState.loggedIn).toEqual(true); done(); // 必须调用done,测试才会结束 }, 3100); })
2. 用async/await结合延迟Promise
把延迟操作包装成Promise,用await等待它完成,这样测试会同步等待异步操作结束:
// 先定义一个通用的延迟函数 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); it('Get Cookie', async () => { await delay(3100); // 等待3.1秒 expect(mobstore.loginState.loggedIn).toEqual(true); })
3. 用Fake Timers跳过真实等待(推荐)
如果这个延迟只是模拟异步操作,没必要真等3.1秒,可以用Jest的Fake Timers快进时间,既保证测试准确性又提升速度:
it('Get Cookie', () => { jest.useFakeTimers(); // 启用假定时器 // 先触发会导致loginState变化的操作(比如登录请求) // 假设这里已经执行了相关逻辑,比如 mobstore.login() setTimeout(() => { expect(mobstore.loginState.loggedIn).toEqual(true); }, 3100); jest.runAllTimers(); // 快进所有定时器,直接执行setTimeout里的断言 })
注意:如果你的异步逻辑是真实的API请求,那Fake Timers不适用,这时候用前两种方法更合适。
内容的提问来源于stack exchange,提问作者Bilal Saeed
相关产品推荐
相关产品推荐

