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

日期单元测试本地通过但Azure Pipeline中失败的原因排查

问题:Jest测试本地通过但Azure Pipeline中失败

背景

我编写了Jest单元测试验证format2APIDate函数,本地执行npm run test所有用例都通过,但合并代码后,最后一个测试用例在Azure Pipeline中失败。

测试代码

import { describe, expect, it } from "@jest/globals"

import { format2APIDate } from "../helpers"

describe("format2APIDate()", () => {
  it("should return a date with the format: YYYY/MM/DD for date with this format YYYY-MM-DD", () => {
    const date = new Date("2024-02-12")

    const formattedDate = format2APIDate(date)

    expect(formattedDate).toBe("2024/02/12")
  })

  it("should return a date with the format: YYYY/MM/DD when a date has this format", () => {
    const date = new Date("Mon Feb 12 2024 00:00:00 GMT+0100 (Central European Standard Time)")

    const formattedDate = format2APIDate(date)

    expect(formattedDate).toBe("2024/02/12")
  })
})

函数实现

export const format2APIDate = (date: Date) => {
  // Format the date as "YYYY/MM/DD"
  const formattedDate = new Date(date)
  return `${formattedDate.getFullYear()}/${String(formattedDate.getMonth() + 1).padStart(2, "0")}/${String(formattedDate.getDate()).padStart(2, "0")}`
}

问题根源

核心是时区差异:

  • 本地测试时,你的机器时区和日期字符串里的GMT+0100一致,解析后getDate()返回12号,符合预期。
  • Azure Pipeline默认使用UTC时区(GMT+0000),解析Mon Feb 12 2024 00:00:00 GMT+0100时,会转换为UTC时间的2024-02-11 23:00:00,此时getDate()返回11号,导致断言失败。

解决办法

1. 改用UTC日期方法

修改函数,使用UTC版本的日期获取方法,确保不受运行环境时区影响:

export const format2APIDate = (date: Date) => {
  const formattedDate = new Date(date)
  return `${formattedDate.getUTCFullYear()}/${String(formattedDate.getUTCMonth() + 1).padStart(2, "0")}/${String(formattedDate.getUTCDate()).padStart(2, "0")}`
}

注意:如果业务需求是取原日期的本地日期而非UTC,这个方案可能不适用,需要同步调整测试预期值。

2. 统一测试环境时区

强制Jest在UTC时区运行测试,同时调整对应测试预期值:

  • 修改Jest配置
    在jest.config.js中添加:
module.exports = {
  // 其他配置项
  testEnvironmentOptions: {
    timezone: 'UTC',
  },
};

然后把第二个测试用例的预期值改成"2024/02/11"(原日期转换为UTC后是2月11号)。

  • 临时设置时区
    在测试文件顶部添加:
process.env.TZ = 'UTC';

同样需要对应调整测试预期值,确保和时区匹配。

3. 使用成熟日期库(推荐)

手动处理日期格式化容易踩时区坑,建议使用date-fns或moment.js这类专业日期库:
以date-fns为例:

import { format } from 'date-fns';

export const format2APIDate = (date: Date) => {
  return format(date, 'yyyy/MM/dd');
}

如果需要指定时区,可以配合date-fns-tz扩展,确保不同环境下结果完全一致。


内容的提问来源于stack exchange,提问作者Ala Eddine Menai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:55:08