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

如何使用Jest在同一个函数中mock两个不同的日期?

解决方案

你遇到的问题本质是全局Date mock返回固定值,导致函数内两次无参构造Date的结果完全一致,有两种可行方案:

方案1:不修改业务代码,调整Mock逻辑

适合不想改动现有上线代码的场景,通过Mock整个Date构造函数,按调用顺序返回不同值即可:

// 测试用例文件的mock配置
const OriginalDate = Date;

beforeAll(() => {
  // 定义两次无参new Date()依次返回的日期
  const mockDates = [
    new OriginalDate('2023-01-05T00:00:00Z'), // 第一个new Date()对应today
    new OriginalDate('2023-01-05T00:00:00Z')  // 第二个new Date()对应nextcollectionDate的初始值
  ];
  let callCount = 0;

  global.Date = jest.fn((...args) => {
    // 带参数的Date调用走原生逻辑,避免破坏setDate等内置方法
    if (args.length) return new OriginalDate(...args);
    return mockDates[callCount++];
  });
  // 继承原生Date的原型和静态方法
  global.Date.prototype = OriginalDate.prototype;
  global.Date.now = jest.fn(() => mockDates[0].getTime());
});

afterAll(() => {
  // 测试结束恢复原生Date,避免影响其他用例
  jest.restoreAllMocks();
});

该方案的缺点是如果后续函数内无参new Date()的顺序/次数变化,mock逻辑需要同步调整,维护成本较高。

方案2:优化函数设计,使用依赖注入(更推荐)

原函数和全局Date强耦合确实会降低可测试性,更合理的写法是把当前日期作为可选参数传入,生产环境不传默认用当前时间,测试环境直接传指定值,完全不需要mock全局对象。

修改后的业务代码:

export const getDateDifference = (collectionDate, today = new Date()) => { 
  // 基于传入的today生成下一个收款日初始值,和原逻辑完全对齐
  const nextcollectionDate = new Date(today.getTime());
  nextcollectionDate.setDate(collectionDate); 

  const differenceInTime = nextcollectionDate.getTime() - today.getTime();
  return (differenceInTime / (1000 * 3600 * 24)).toFixed(0);
};

测试用例直接传参即可,无需任何mock:

test('计算1月5号到1月15号的日期差为10', () => {
  const testToday = new Date('2023-01-05T00:00:00Z');
  expect(getDateDifference(15, testToday)).toBe('10');
});

该方案逻辑更清晰,没有全局依赖,测试成本低,后续迭代不容易出问题。


内容的提问来源于stack exchange,提问作者coding1223322

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:54:09