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

如何用Jest模拟Date()修改Vue中export default外的常量日期

问题分析

你遇到的核心问题是:模块级变量formatCurrentDate在组件模块加载阶段就已执行计算,而Jest的jest.useFakeTimers()和jest.setSystemTime()是在beforeEach中才设置的——这时候组件模块已经加载完成,formatCurrentDate早就用真实时间计算好了,自然不会受后续fake timers的影响。

而data中的currentDate是在组件初始化时执行的,此时beforeEach已经完成fake timers的设置,所以能正确拿到mock的系统时间。

解决方案

提供两种可行方案,根据你的实际场景选择:

方案1:修改Vue组件代码,延迟formatCurrentDate的计算时机

把模块级的直接赋值改成函数,或者将其移入组件的计算属性/生命周期钩子,确保它在组件初始化(此时fake timers已生效)后再执行:

<script>
import dateFormat from 'dateformat';

// 改成函数,需要使用时再调用
const getFormatCurrentDate = () => dateFormat(new Date(), 'yyyy/mm/dd');

export default {
  data() {
    // 注意:原代码data选项缺少return,这是Vue单文件组件的错误写法,必须修正
    return {
      currentDate: dateFormat(new Date(), 'yyyy-mm-dd'),
    };
  },
  // 如果formatCurrentDate需要在组件模板或逻辑中使用,推荐用计算属性
  computed: {
    formatCurrentDate() {
      return dateFormat(new Date(), 'yyyy/mm/dd');
    }
  }
};
</script>

这样在测试时,只要组件初始化完成,调用getFormatCurrentDate()或者访问formatCurrentDate计算属性,都会使用mock的系统时间。

方案2:在测试文件中提前设置fake timers(在导入组件前)

模块导入是同步执行的,所以要在导入组件之前就配置好fake timers和mock时间,确保组件模块加载时formatCurrentDate的计算能用到mock时间:

const systemDate = new Date('2022-06-23 13:29:00');

// 关键:先设置fake timers和系统时间,再导入组件
jest.useFakeTimers();
jest.setSystemTime(systemDate);

// 此时导入组件,模块级的formatCurrentDate会用mock时间计算
import YourVueComponent from '@/path/to/your/component.vue';

afterAll(() => {
  jest.useRealTimers();
});

// 若有多个测试用例,可在beforeEach中重置系统时间
beforeEach(() => {
  jest.setSystemTime(systemDate);
});

// 测试用例示例
test('formatCurrentDate uses mocked date', () => {
  // 假设formatCurrentDate是组件模块导出的变量(若要访问需确保它被导出)
  expect(YourVueComponent.__moduleExports.formatCurrentDate).toBe('2022/06/23');
});
额外提示

原Vue组件的data选项写法有误:data必须是一个返回对象的函数,否则多个组件实例会共享同一份数据。请务必修正为带return的写法,避免后续出现意外问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:54:31