事先,感谢您提供的任何帮助/建议!
我正在尝试找到一种优雅的方法来测试创建Mongoose模型实例的日期/时间。
我想确保存储的时间是正确的时间。
我的模特目前看起来像这样:
const messageSchema = mongoose.Schema({
user: { type: String, required: true },
message: { type: String, required: true },
created: { type: Date, default: Date.now },
});
const Message = mongoose.model('Message', messageSchema);
我将这个模型导入到mocha测试套件中,我试图按照以下方式进行测试:
const now = {Date message was created}
it('check time matches time created', () => {
expect(message.created).to.equal(now);
});
我尝试实现此目的的方法是使用Sinon's Fake timers功能。
所以我的测试用例如下:
describe('creating new message', () => {
let clock;
let message;
let now;
before(() => {
clock = sinon.useFakeTimers();
clock.tick(100);
message = new Message({
user: 'Test User',
message: 'Test Message',
});
// Time the message was created
now = Date.now();
clock.tick(100);
});
it('check time matches time created', () => {
expect(message.created).to.equal(now);
});
});
我认为这不起作用,因为作为Mongoose模型的默认值传递的Date.now
函数与Sinon假计时器隔离(伪计时器在测试文件中,模型是从另一个文件导入)。
再次感谢你!
答案 0 :(得分:2)
只需将Date.now
包装在匿名函数中,就像那样:
function() { return Date.now(); }
或ES6版
() => Date.now()
因此Schema会变成类似的东西:
const messageSchema = mongoose.Schema({
user: { type: String, required: true },
message: { type: String, required: true },
created: { type: Date, default: () => Date.now() },
});
因为当你执行sinon.useFakeTimers()
时,sinon在后面做的是覆盖global
属性Date
。
调用Date
与调用global.Date
相同。
当您将Date.now
传递给mongoose时,您实际上是在传递global.Date
引用的Node内部方法,而mongoose会调用此方法,不再访问global.Date
参考。
但是,根据我的解决方案,我们传递了一个方法,在调用时,会访问global.Date
的引用,现在由Sinon存根
为了在实践中看到这种行为,您可以在Javascript中执行以下操作:
var nativeDate = Date; // accessing global.Date
Date = { now: () => 1 }; // overrides global.Date reference to a entirely new object
console.log(Date.now()); // now it outputs 1
console.log(nativeDate.now()); // outputs current date, stub doesn't work here, because it's calling the javascript native Date method, and not global.Date anymore