如何使用 Jest 模拟日期对象?



我正在研究一个测试用例,我需要比较期望块中的日期字段(creation_timelast_attempt_time(。有时它会由于日期中的毫秒值更改而失败。所以我需要模拟一个应该返回指定日期的日期对象,并且它应该用于所有测试用例模块,只要在项目的测试用例中使用 Date 对象。

// sample.test.ts
it('should return an reset object', () => {
// Preparing
const updatedChangeRequest: any = {
creation_time: new Date(),
attempts: 0,
last_attempt_time: new Date()
};
// Executing
const result = ClassName.methodName();
// Verifying
expect(result).toEqual(updatedChangeRequest);
});

这里有几个选择。例如,您可以重新分配整个Date对象并将其替换为模拟实现或重写单个方法(然后在运行测试用例后还原它们(。但是在 npm 中已经有一个名为mockdate的模块。

使用模拟日期,您可以执行以下操作:

const MockDate = require('mockdate');
it('should return an reset object', () => {       
MockDate.set(Date.now()); // sets now to Date.now()
// Preparing
const updatedChangeRequest: any = {
creation_time: new Date(),
attempts: 0,
last_attempt_time: new Date()
};
// Executing
const result = ClassName.methodName();
// Verifying
expect(result).toEqual(updatedChangeRequest);
MockDate.reset();
});

要在所有测试文件中模拟Date,您可以在 jest 配置文件中设置setupFilesAfterEnv

// jest.config.js
{
// ...
setupFilesAfterEnv: [
"./mockdate.js"
]
}
// mockdate.js
const MockDate = require('mockdate');
beforeAll(() => {
MockDate.set(Date.now());
});
afterAll(() => {
MockDate.reset();
});

若要确认它是否有效,可以运行以下测试:

// mockdate.test.js
test('It Should always return the same value for Date.now()', async () => {
const before = Date.now();
await new Promise((resolve, reject) => setTimeout(resolve, 1000));
const after = Date.now();
expect(before).toEqual(after);
});

最新更新