我想测试
scheduleJob
包中的 node-schedule
。有了 sinon useFakeTimers()
我可以跳过时间。不幸的是,我的调度程序似乎并不“相信”假时间。当我将调度程序设置为 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));
有人有什么想法吗?
@MPasman
您的测试是什么样的?节点调度作者用 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 中执行此操作,它在每个单元测试之后运行)。 Node-schedule 还提供了一个名为
scheduledJobs
的函数,它返回一个包含所有已调度函数的对象。你可以循环它并取消它们)
3) 将
cronTime
设置为每秒运行一次,以便于测试
4)将时钟滴答一秒多一点(在我的例子中,我做了 3 秒多一点)
5)取消作业以停止它(否则它将继续运行并且您的测试将超时)。
6)期望你的函数被调用 x 次
希望这对您有帮助。
基本上
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/
希望这能让它更清楚一点
@nsikimic 响应的最后一部分是错误的,
node-schedule
确实通过库使用了setTimeout
long-timeout
https://github.com/node-schedule/node-schedule/blob/master/lib/Inspiration.js#L3 https://github.com/tellnes/long-timeout/blob/master/index.js#L41