使用 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 测试他们的代码,所以我不明白为什么这会成为一个问题。

see this for examples

我能够像这样使用 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 次

希望对您有所帮助。