【问题标题】:Test node-schedule with sinon FakeTimers使用 sinon FakeTimers 测试节点调度
【发布时间】:2018-08-31 13:56:36
【问题描述】:

我想从node-schedule 包中测试我的scheduleJob。有了 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));

有人知道吗?

【问题讨论】:

    标签: javascript node.js sinon


    【解决方案1】:

    @MPasman

    你的测试是什么样的?节点调度作者用 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 中执行此操作,该操作在每个单元测试之后运行)。 Node-schedule 还提供了一个名为scheduledJobs 的函数,它返回一个包含所有已调度函数的对象。您可以循环并取消它们)

    3) 将cronTime 设置为每秒运行一次,以便于测试

    4) 时钟滴答一秒多一点(在我的例子中,我做了 3 秒多一点)

    5) 取消作业以停止它(否则它将继续运行并且您的测试将超时)。

    6) 期望您的函数被调用 x 次

    希望对你有所帮助。

    【讨论】:

    • 感谢您的帮助!我试试看。
    【解决方案2】:

    基本上sinon.useFakeTimers() 方法将 setInterval 和 setTimeout 异步方法替换为您可以使用 clock.tick() 控制的内置同步方法

    clock.tick(time)方法调用被替换的同步方法,基本上按time指定的时间转发。

    另一方面,node-schedulecron-like 作业调度程序,因此它不使用 setInterval 和 setTimeout

    https://www.npmjs.com/package/node-schedule

    https://sinonjs.org/releases/v1.17.6/fake-timers/

    希望这能让它更清楚一点

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      • 2023-03-22
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      相关资源
      最近更新 更多