【发布时间】:2019-01-14 03:09:40
【问题描述】:
我正在尝试在 Jest 中编写单元测试,以利用 moment.js 库来模拟几部分代码。为了完整起见,这是一个 Node+Express 项目,使用 TypeScript 编写,并带有支持的 moment.d.ts 文件。
我正在尝试测试的导入和代码块:
import moment from 'moment';
const durationSinceLastEmail = moment.duration(moment(new Date())
.diff(moment(user.passwordRecoveryTokenRequestDate)));
为导入的矩参考提供的类型信息列出了两个实际项目:
(alias) function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, strict?: boolean): moment.Moment (+1 overload)
(alias) namespace moment
import moment
我的实现代码使用两种形式:moment.duration 用于命名空间,moment(...params) 用于函数。
我的一般 Jest 嘲讽策略并不是很有效。例如)
jest.mock('moment', () => {
return jest.fn().mockImplementation( () => {
return {
duration: (...params) => mockDuration(...params)
};
});
});
我已经成功地模拟了持续时间函数,方法是直接替换持续时间方法,以更强有力的方式。
const originalDuration: Function = moment.duration;
mockDuration.mockImplementation((...params) => {
const original = originalDuration(...params);
// Apply mocks on returning object here
// or supply entirely new mock object
return original;
});
moment.duration = mockDuration;
坦率地说,代码很糟糕,但它让我走到了一半,因为这让我可以捕获对moment.duration(...params) 的调用,但是我尝试模拟moment(...) 调用的每种方法要么不起作用,要么与上述方法完全冲突(也不起作用)。
命名冲突似乎是我问题的根源,所以我的问题是:
1) 无论如何,我是否可以将这些不同的引用分开,以便明确处理它们?
或
2) 我有没有一种有效的方法来分别模拟它们,或者在单个模拟对象中同时为函数和命名空间提供模拟?
【问题讨论】:
-
听起来您最感兴趣的是监视对
moment()和moment.duration()的调用,而对替换它们的实现不太感兴趣,对吗? -
监视这些很好-但是,我想模拟
diff()函数的实现(在从moment()返回的对象上提供)-我一直在尝试模拟moment()为了访问这个方法。
标签: typescript momentjs jestjs