如何在JavaScript中用Jest编写特定日期及时区的测试?
Jest 特定日期与时区测试解决方案
1. 自定义CustomDate对象的时间模拟问题
jest.setSystemTime() 仅对原生Date生效,你的CustomDate没跟着生效,大概率是它的构造逻辑没复用被Mock的全局Date,或者内部绕过了全局Mock。
解决办法:
- 直接Mock全局
Date,让CustomDate继承这个Mock版本:beforeEach(() => { const targetDate = new Date('2024-01-01T00:00:00Z'); jest.spyOn(global, 'Date').mockImplementation(() => targetDate); }); afterEach(() => { jest.restoreAllMocks(); }); - 检查
CustomDate的实现代码,确保它内部调用的是全局作用域的Date,而不是硬编码的原生构造函数。
2. 测试内部动态切换时区
Node.js会缓存process.env.TZ的读取结果,直接修改它不会对已加载的模块生效,得结合模块隔离来实现动态切换:
方法一:用jest.isolateModules重新加载目标模块
test('验证悉尼时区下的逻辑', () => { process.env.TZ = 'Australia/Sydney'; jest.isolateModules(() => { // 在这里导入需要测试的模块,此时模块内的Date会使用新时区 const { calculateTime } = require('./time-utils'); expect(calculateTime()).toBe('2024-01-01 10:00:00'); }); }); test('验证纽约时区下的逻辑', () => { process.env.TZ = 'America/New_York'; jest.isolateModules(() => { const { calculateTime } = require('./time-utils'); expect(calculateTime()).toBe('2023-12-31 19:00:00'); }); });
方法二:Mock Date的时区相关方法
如果不需要真实时区环境,只是验证输出格式,直接MocktoLocaleString、toISOString等方法即可:
test('模拟悉尼时区的时间输出', () => { jest.spyOn(Date.prototype, 'toLocaleString') .mockReturnValue('2024-01-01 10:00:00'); const { formatTime } = require('./time-utils'); expect(formatTime()).toBe('2024-01-01 10:00:00'); });
注意:测试后要清理process.env.TZ,避免影响其他测试:
afterEach(() => { delete process.env.TZ; });
内容的提问来源于stack exchange,提问作者Adriano174
相关产品推荐
相关产品推荐

