如果在超时后重复调用该方法,如何在sinon中测试

问题描述 投票:1回答:1

我有一个方法启动,在setTimeout之后调用自己。它检查是否有记录,然后在没有找到记录时调整超时。我想在sinon中测试它,如果它反复调用的话。

以下是代码正在执行的操作,这是一个侦听记录是否处于活动状态的进程。 fetchAndMarkRecordAsActive方法从DB获取记录然后重复该方法本身,如果没有找到记录,则将超时更改为大约一小时的更长超时。但是如果记录仍在提取超时,则默认约10分钟。

ProcessReader.prototype.start = function () {
    const self = this;

    this.fetchAndMarkRecordAsActive(function (error) {
        if (error === 'NO_RECORD_FOUND') {
            self.timeout = self.longTimeout;
        }

        setTimeout(function () {
            self.start();
        }, self.timeout);
    });
}

我应该如何使用sinon进行测试?

以下是我想要实现的以下测试用例:

  • 它应该在超时后调用自己
  • 如果找到记录,它应该反复调用

任何帮助表示赞赏。

更新:

this.longTimeout改为self.longTimeout。我的错

javascript timeout mocha sinon
1个回答
1
投票

这应该让你开始:

const sinon = require('sinon');

describe('ProcessReader', () => {

  let startSpy;
  let fetchStub;
  let clock;

  beforeEach(() => {
    startSpy = sinon.spy(ProcessReader.prototype, 'start');
    fetchStub = sinon.stub(ProcessReader.prototype, 'fetchAndMarkRecordAsActive');
    clock = sinon.useFakeTimers();
  });

  afterEach(() => {
    startSpy.restore();
    fetchStub.restore();
    clock.restore();
  });

  it('should work as expected', () => {
    const reader = new ProcessReader();

    fetchStub.yields();  // simulate records returned
    reader.start();
    sinon.assert.callCount(startSpy, 1);   // 1
    sinon.assert.callCount(fetchStub, 1);  // 1
    clock.tick(300000);  // wait half the timeout
    sinon.assert.callCount(startSpy, 1);   // still 1
    sinon.assert.callCount(fetchStub, 1);  // still 1
    clock.tick(300000);  // wait the other half
    sinon.assert.callCount(startSpy, 2);   // 2
    sinon.assert.callCount(fetchStub, 2);  // 2
    clock.tick(600000);  // wait the timeout
    sinon.assert.callCount(startSpy, 3);   // 3
    sinon.assert.callCount(fetchStub, 3);  // 3
    fetchStub.yields('NO_RECORD_FOUND');  // now simulate end of records
    clock.tick(600000);  // wait the timeout
    sinon.assert.callCount(startSpy, 4);   // 4
    sinon.assert.callCount(fetchStub, 4);  // 4
    clock.tick(600000);  // wait the timeout
    sinon.assert.callCount(startSpy, 4);   // still 4
    sinon.assert.callCount(fetchStub, 4);  // still 4
    clock.tick(3000000); // wait the rest of longTimeout
    sinon.assert.callCount(startSpy, 5);   // 5
    sinon.assert.callCount(fetchStub, 5);  // 5
    clock.tick(3600000); // wait longTimeout
    sinon.assert.callCount(startSpy, 6);   // 6
    sinon.assert.callCount(fetchStub, 6);  // 6
  });

});

请注意,您还应该使用self访问longTimeout


这里参考的是我用来创建上述测试的代码:

const ProcessReader = function () {
  this.longTimeout = 3600000;
  this.timeout = 600000;
}

ProcessReader.prototype.fetchAndMarkRecordAsActive = function () { }

ProcessReader.prototype.start = function () {
  const self = this;

  this.fetchAndMarkRecordAsActive(function (error) {
    if (error === 'NO_RECORD_FOUND') {
      self.timeout = self.longTimeout;  // <= use self.longTimeout
    }

    setTimeout(function () {
      self.start();
    }, self.timeout);
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.