开玩笑的打字稿 - 模拟日期构造函数
Posted
技术标签:
【中文标题】开玩笑的打字稿 - 模拟日期构造函数【英文标题】:jest typescript - Mock Date constructor 【发布时间】:2020-07-09 17:28:45 【问题描述】:我正在尝试模拟 new Date()
以返回特定日期。以下代码:
const now = new Date()
jest.spyOn(global, 'Date').mockImplementation(() => now)
给出编译错误:Argument of type '() => Date' is not assignable to parameter of type '() => string'. Type 'Date' is not assignable to type 'string'
。
我认为原因是 jest 认为我试图模拟 Date()
而不是 new Date()
。实际上,Date()
返回一个字符串。我该如何解决这个问题?
【问题讨论】:
找到解决方案了吗? 不。我使用了一种解决方法:我只在我的代码中使用new Date(Date.now())
而从不使用new Date()
。这样我就可以模拟Date.now()
。
【参考方案1】:
一种解决方法是使用mockdate 库,可用于在“现在”时进行更改。
const MockDate = require('mockdate');
test('Mock Date to change when "now" is', () =>
console.log('Normal: ', new Date().getTime());
MockDate.set(new Date(1466424490000));
console.log('Mocked: ', new Date().getTime());
MockDate.reset();
console.log('Restored: ', new Date().getTime());
);
而测试结果是这样的:
$ npm run test
> jest
PASS src/test.ts
✓ Mock Date to change when "now" is (8ms)
console.log src/test.ts:4
Normal: 1585505136315
console.log src/test.ts:8
Mocked: 1466424490000
console.log src/test.ts:12
Restored: 1585505136322
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.804s
见the reference project on GitHub。
【讨论】:
谢谢。我认为该库之所以有效,是因为它使用的是 JS,而不是 TypeScript。我怀疑问题出在从 TS 到 JS 的翻译上。我正在寻找 TS 解决方案。 @EllaSharakanski 这个库现在在 TS 中。【参考方案2】:好吧,我试过这个解决方案,它奏效了..
class MockDate extends Date
constructor()
super("2020-05-14T11:01:58.135Z"); // add whatever date you'll expect to get
在该测试的 beforeEach 中,我添加了:
// @ts-ignore
global.Date = MockDate;
这样,每当我调用一个内部有 new Date() 的函数时,它都会返回我在上面的 MockDate 类的构造函数中添加的日期!
【讨论】:
你可以通过附加到你的类声明as unknown as typeof Date
来避免//@ts-ignore
。
Jest 不建议这样做。您应该将 Jest Spies 用于任何全局类。
好主意!但是当调用data.getFullYear()
我得到this is not a Date object.
【参考方案3】:
告诉编译器它想听什么:说它是一个转换为未知的字符串,然后是转换为字符串:
const now = new Date() as unknown as string
【讨论】:
这对嘲笑没有帮助 从 Aaron Goldman 的评论中你可以推断出他的意思是const mockDate = new Date(1466424490000) const spy = jest.spyOn(global, 'Date') .mockImplementation(() => mockDate as unknown as string)
但是 new Date() 现在返回一个字符串以及对 new Date() 的任何调用,例如new Date().getTime() 将不起作用,因为 "string".getTime() 不是函数【参考方案4】:
Daryn 对 Arron 的回答的推理评论在没有额外包的情况下效果很好。
const mockDate = new Date();
jest.spyOn(global, "Date").mockImplementation(() => (mockDate as unknown) as string);
const myDate = new Date();
【讨论】:
终于!这对我有用【参考方案5】:我在使用 jest typescript 模拟 new Date()
时遇到了同样的问题
当尝试在函数中模拟 Date 时:
export const checkValidTime(): boolean =>
const now = new Date();
const maxAllowTime = new Date('2020-02-02 09:00:00');
console.log(`currentTime: $now.toLocaleString()`);
console.log(`maxAllowTime: $maxAllowTime.toLocaleString()`);
return now > maxAllowTime;
单元测试中的模拟解决方案:
const mockDate = new Date('2021-09-03 08:00:10');
jest
.spyOn(global, 'Date')
.mockImplementationOnce(() => (mockDate as unknown) as string);
const valid = checkDateTime();
expect(valid).toEqual(true);
【讨论】:
以上是关于开玩笑的打字稿 - 模拟日期构造函数的主要内容,如果未能解决你的问题,请参考以下文章