Jest测试问题:TypeScript随机数值导致测试失败
问题分析与解决方案
问题根源
你把@emotion/styled从v10升级到了v11,这个大版本迭代引入了额外的运行时逻辑(比如样式处理的异步初始化、性能优化相关的计算),导致instrumentPromise计算Promise拒绝耗时的时候,不再是理想的0毫秒,而是产生了微小的实际执行耗时。新增的eslint-plugin-jsdoc和@emotion/styled-base版本更新和这个问题无关,核心原因是Emotion v11的运行时开销变化。
测试修复方案
你不需要预测这个小数数值,直接修改测试用例,让它兼容微小的时间差异即可,以下是几种可行方案:
方案1:允许数值误差(推荐)
用Jest的toBeCloseTo匹配器,设置合理的误差范围:
expect(spy).toHaveBeenCalledWith( expect.objectContaining({ groupNamespace: "global", milliseconds: expect.toBeCloseTo(0, 2), // 允许两位小数的误差 operationName: "name", success: false, }) );
方案2:只验证数值类型或范围
如果不需要精确验证耗时,只确认是合法数字即可:
expect(spy).toHaveBeenCalledWith( expect.objectContaining({ groupNamespace: "global", milliseconds: expect.any(Number), operationName: "name", success: false, }) );
或者验证数值非负:
expect(spy).toHaveBeenCalledWith( expect.objectContaining({ groupNamespace: "global", milliseconds: expect.greaterThanOrEqual(0), operationName: "name", success: false, }) );
方案3:Mock时间精确控制
如果instrumentPromise是基于Date或performance.now()计算耗时,用Jest的假计时器冻结时间:
beforeAll(() => { jest.useFakeTimers(); }); afterAll(() => { jest.useRealTimers(); }); test('should log on promise rejecting', () => { jest.setSystemTime(new Date('2023-01-01')); const promise = Promise.reject(new Error('test')); const spy = jest.fn(); void instrumentPromise(promise, "name").catch(() => { expect(spy).toHaveBeenCalledWith({ groupNamespace: "global", milliseconds: 0, operationName: "name", success: false, }); }); jest.runAllTimers(); });
注意事项
- 测试里别硬编码依赖运行时环境的数值(比如耗时),这类值会随依赖版本、Node.js版本、硬件性能波动。
- 大版本升级(比如v10→v11)往往伴随运行时行为变化,更新后优先排查这类测试兼容性问题。
内容的提问来源于stack exchange,提问作者user3927038
相关产品推荐
相关产品推荐

