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

如何为Jest的部分测试用例设置不同的TZ环境变量?

解决Jest中部分测试用例多时区运行的问题

问题根源

你遇到的两个核心问题本质原因如下:

  1. 命令行设置TZ属于进程级配置,每次启动Jest只能生效一个时区,重复命令的方式扩展性极差;
  2. 直接在beforeEach中修改process.env.TZ无效,是因为Node.js在启动时就已读取时区配置并初始化了Date等核心模块的行为,运行时修改环境变量不会自动更新这些模块的时区逻辑。

可行解决方案

方案1:按时区拆分测试文件,独立运行

将不同时区的测试用例拆分到对应命名的文件中(比如xxx.sp.test.js对应圣保罗时区,xxx.sh.test.js对应上海时区),然后在package.json中配置针对性的脚本:

{
  "scripts": {
    "test:sp": "TZ=America/Sao_Paulo jest --testPathPattern=.*\\.sp\\.test\\.js$",
    "test:sh": "TZ=Asia/Shanghai jest --testPathPattern=.*\\.sh\\.test\\.js$",
    "test:all": "npm run test:sp && npm run test:sh"
  }
}
  • 新增时区时,只需添加对应的脚本和文件命名规则即可,扩展性强;
  • 每个时区的测试进程独立,不会互相干扰。

方案2:单测试文件内动态切换时区(需重置模块)

如果不想拆分文件,可以在测试块中设置时区后,通过jest.resetModules()重置已加载的模块,再动态导入被测代码,确保新时区生效:

describe('圣保罗时区测试', () => {
  beforeAll(() => {
    process.env.TZ = 'America/Sao_Paulo';
    jest.resetModules(); // 重置已加载模块,让后续导入的代码使用新时区
  });

  test('格式化UTC时间为当地时间', () => {
    // 动态导入被测模块,而非在文件顶部导入
    const { formatUtcToLocal } = require('../src/date-handler');
    expect(formatUtcToLocal('2024-05-20T00:00:00Z')).toBe('2024-05-19 19:00:00');
  });
});

describe('上海时区测试', () => {
  beforeAll(() => {
    process.env.TZ = 'Asia/Shanghai';
    jest.resetModules();
  });

  test('格式化UTC时间为当地时间', () => {
    const { formatUtcToLocal } = require('../src/date-handler');
    expect(formatUtcToLocal('2024-05-20T00:00:00Z')).toBe('2024-05-20 08:00:00');
  });
});
  • 核心是在设置时区后重置模块,再动态导入被测代码,确保代码加载时使用新的时区配置;
  • 注意不要在测试文件顶部提前导入被测模块,否则会使用默认时区加载,后续修改无效。

方案3:使用第三方库简化操作

可以借助jest-timezone库来处理时区切换的细节,无需手动重置模块:

  1. 安装依赖:
npm install --save-dev jest-timezone
  1. 在测试中使用:
const { setTimeZone } = require('jest-timezone');

describe('圣保罗时区测试', () => {
  beforeAll(() => setTimeZone('America/Sao_Paulo'));

  test('验证当地时间', () => {
    expect(new Date('2024-05-20T00:00:00Z').toLocaleString()).toContain('5/19/2024');
  });
});

describe('上海时区测试', () => {
  beforeAll(() => setTimeZone('Asia/Shanghai'));

  test('验证当地时间', () => {
    expect(new Date('2024-05-20T00:00:00Z').toLocaleString()).toContain('2024/5/20');
  });
});
  • 该库内部自动处理了模块重置和时区环境变量的生效逻辑,使用更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:01:08