You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:21:02