使用 sinon FakeTimers 测试节点调度
Test node-schedule with sinon FakeTimers
我想从 node-schedule
包中测试我的 scheduleJob
。使用 sinon useFakeTimers()
我可以跳过时间。不幸的是,我的调度程序似乎没有 'believe' 假时间。当我将调度程序设置为 1 分钟时,它可以完美运行,所以我知道它可以运行。我也试过在通话前一分钟设置假时间,也没有用。
诗乃:
let clock = sinon.useFakeTimers(moment().toDate());
clock.tick(60*60*23);
我的预定工作:
let job_2 = schedule.scheduleJob(new Date(date.toISOString()), function (user) {
console.log("get's here..");
if (user.status === 'pending') {
user.remove(function (error) {
if (!error) {
mid.addEvent({
action: 'deleted_user'
}, {
name: user.name
}, function (error) {
if (error) {
console.log("error: " + error);
}
});
}
});
}
}.bind(null, user));
有人知道吗?
基本上 sinon.useFakeTimers()
方法将 setInterval 和 setTimeout 异步方法替换为您可以使用 clock.tick()
控制的内置同步方法
clock.tick(time)
方法调用替换的同步方法,基本上按指定的 time
转发时间。
另一方面,node-schedule
是一个 cron-like
作业调度程序,因此它不使用 setInterval 和 setTimeout
https://www.npmjs.com/package/node-schedule
https://sinonjs.org/releases/v1.17.6/fake-timers/
希望这能让它更清楚一点
@MPasman
你的测试是什么样的? node-schedule 作者使用 sinon 测试他们的代码,所以我不明白为什么这会成为一个问题。
我能够像这样使用 jasmine 的 fakeAsync 在 angular 6 中测试我的工作:
it('should call appropriate functions when cronJob is triggered, bad ass test',
fakeAsync(() => {
const channelSpy = spyOn(messengerService, 'createChannels');
const listenerSpy = spyOn(messengerService, 'createListener');
const messengerSpy = spyOn(messengerService.messenger,
'unsubscribeAll');
// reset your counts
channelSpy.calls.reset();
listenerSpy.calls.reset();
messengerSpy.calls.reset();
messengerService.cronJob.cancel();
// run cron job every second
messengerService.cronJobTime = '* * * * * *';
messengerService.scheduleMyJsCronJob();
tick(3150);
messengerService.cronJob.cancel();
expect(channelSpy.calls.count()).toEqual(3);
expect(listenerSpy.calls.count()).toEqual(3);
expect(messengerSpy.calls.count()).toEqual(3);
}));
我正在测试的服务中的实际功能:
scheduleMyJsCronJob(): void {
this.cronJob = scheduleJob(this.cronJobTime, () => {
// logic to unsubscribe at midnight
this.messenger.unsubscribeAll();
// create new channels
this.createChannels(
this.sessionStorageService.getItem('general-settings'));
this.createListener(
this.sessionStorageService.getItem('general-settings'));
});
}
基本策略是:
1) 监视你的 cronJob 在计划时应该调用的函数
2) 取消所有以前的作业(如果有)(您也可以在 afterEach 中执行此操作,每个单元测试后 运行s)。 Node-schedule 还提供了一个名为 scheduledJobs
的函数,其中 returns 是一个包含所有已调度函数的对象。你可以遍历它并取消它们)
3) 每秒将 cronTime
设置为 运行 以便于测试
4) 时钟滴答一秒多一点(在我的例子中我做了 3 秒多一点)
5) 取消作业以停止它(否则它将保持 运行ning 并且您的测试将超时)。
6) 期望您的函数被调用 x 次
希望对您有所帮助。
我想从 node-schedule
包中测试我的 scheduleJob
。使用 sinon useFakeTimers()
我可以跳过时间。不幸的是,我的调度程序似乎没有 'believe' 假时间。当我将调度程序设置为 1 分钟时,它可以完美运行,所以我知道它可以运行。我也试过在通话前一分钟设置假时间,也没有用。
诗乃:
let clock = sinon.useFakeTimers(moment().toDate());
clock.tick(60*60*23);
我的预定工作:
let job_2 = schedule.scheduleJob(new Date(date.toISOString()), function (user) {
console.log("get's here..");
if (user.status === 'pending') {
user.remove(function (error) {
if (!error) {
mid.addEvent({
action: 'deleted_user'
}, {
name: user.name
}, function (error) {
if (error) {
console.log("error: " + error);
}
});
}
});
}
}.bind(null, user));
有人知道吗?
基本上 sinon.useFakeTimers()
方法将 setInterval 和 setTimeout 异步方法替换为您可以使用 clock.tick()
clock.tick(time)
方法调用替换的同步方法,基本上按指定的 time
转发时间。
node-schedule
是一个 cron-like
作业调度程序,因此它不使用 setInterval 和 setTimeout
https://www.npmjs.com/package/node-schedule
https://sinonjs.org/releases/v1.17.6/fake-timers/
希望这能让它更清楚一点
@MPasman
你的测试是什么样的? node-schedule 作者使用 sinon 测试他们的代码,所以我不明白为什么这会成为一个问题。
我能够像这样使用 jasmine 的 fakeAsync 在 angular 6 中测试我的工作:
it('should call appropriate functions when cronJob is triggered, bad ass test',
fakeAsync(() => {
const channelSpy = spyOn(messengerService, 'createChannels');
const listenerSpy = spyOn(messengerService, 'createListener');
const messengerSpy = spyOn(messengerService.messenger,
'unsubscribeAll');
// reset your counts
channelSpy.calls.reset();
listenerSpy.calls.reset();
messengerSpy.calls.reset();
messengerService.cronJob.cancel();
// run cron job every second
messengerService.cronJobTime = '* * * * * *';
messengerService.scheduleMyJsCronJob();
tick(3150);
messengerService.cronJob.cancel();
expect(channelSpy.calls.count()).toEqual(3);
expect(listenerSpy.calls.count()).toEqual(3);
expect(messengerSpy.calls.count()).toEqual(3);
}));
我正在测试的服务中的实际功能:
scheduleMyJsCronJob(): void {
this.cronJob = scheduleJob(this.cronJobTime, () => {
// logic to unsubscribe at midnight
this.messenger.unsubscribeAll();
// create new channels
this.createChannels(
this.sessionStorageService.getItem('general-settings'));
this.createListener(
this.sessionStorageService.getItem('general-settings'));
});
}
基本策略是:
1) 监视你的 cronJob 在计划时应该调用的函数
2) 取消所有以前的作业(如果有)(您也可以在 afterEach 中执行此操作,每个单元测试后 运行s)。 Node-schedule 还提供了一个名为 scheduledJobs
的函数,其中 returns 是一个包含所有已调度函数的对象。你可以遍历它并取消它们)
3) 每秒将 cronTime
设置为 运行 以便于测试
4) 时钟滴答一秒多一点(在我的例子中我做了 3 秒多一点)
5) 取消作业以停止它(否则它将保持 运行ning 并且您的测试将超时)。
6) 期望您的函数被调用 x 次
希望对您有所帮助。