如何模拟像 new Date() 这样的构造函数

新手上路,请多包涵

我有一个方法依赖于 new Date 创建一个日期对象然后对其进行操作。我正在测试操作是否按预期工作,因此我需要将返回日期与预期日期进行比较。为此,我需要确保 new Date 在测试和被测试的方法中返回相同的值。我怎样才能做到这一点?

有没有办法实际模拟构造函数的返回值?

我可以创建一个模块,该模块需要一个提供日期对象并可以被模拟的函数。但这在我的代码中似乎是一个不必要的抽象。

要测试的示例函数…

 module.exports = {
  sameTimeTomorrow: function(){
    var dt = new Date();
        dt.setDate(dt + 1);
    return dt;
  }
};

我如何模拟 new Date() 的返回值?

原文由 Seth Feldkamp 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 689
2 个回答

更新:这个答案是 jest < version 26 最近的笑话版本见这个答案


您可以使用 jest.spyOn 模拟像 new Date() 这样的构造函数,如下所示:

 test('mocks a constructor like new Date()', () => {
  console.log('Normal:   ', new Date().getTime())

  const mockDate = new Date(1466424490000)
  const spy = jest
    .spyOn(global, 'Date')
    .mockImplementation(() => mockDate)

  console.log('Mocked:   ', new Date().getTime())
  spy.mockRestore()

  console.log('Restored: ', new Date().getTime())
})

输出看起来像:

 Normal:    1566424897579
Mocked:    1466424490000
Restored:  1566424897608

请参阅 GitHub 上的参考项目

注意:如果您使用的是 TypeScript 并且会遇到编译错误, Argument of type '() => Date' is not assignable to parameter of type '() => string'. Type 'Date' is not assignable to type 'string' 。在这种情况下,一种解决方法是使用 mockdate 库,它可用于更改“现在”的时间。有关详细信息,请参阅 此问题

原文由 Yuci 发布,翻译遵循 CC BY-SA 4.0 许可协议

从 jest 26 开始,您可以使用支持方法 jest.setSystemTime 的“现代”fakeTimers 实现( 参见此处的文章)。

 beforeAll(() => {
    jest.useFakeTimers('modern');
    jest.setSystemTime(new Date(2020, 3, 1));
});

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

请注意, 'modern' 将是 jest 版本 27 的默认实现。

在此处 查看 setSystemTime 的文档。

原文由 ThdK 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题