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

Javascript 如果超时后重复调用该方法,如何在sinon中进行测试,javascript,timeout,mocha.js,sinon,Javascript,Timeout,Mocha.js,Sinon,我有一个方法start,它在setTimeout之后调用自己。它检查是否有记录,如果没有记录,则调整超时。如果它反复呼叫,我想在sinon中测试它 下面是代码所做的,这是一个监听记录是否处于活动状态的过程。fetchAndMarkRecordAsActive方法从数据库中获取一条记录,然后重复该方法本身,如果没有找到记录,它会将超时时间更改为更长的超时时间,大约一个小时。但如果记录仍在获取,则默认超时时间保持在10分钟左右 ProcessReader.prototype.start = func

我有一个方法start,它在setTimeout之后调用自己。它检查是否有记录,如果没有记录,则调整超时。如果它反复呼叫,我想在sinon中测试它

下面是代码所做的,这是一个监听记录是否处于活动状态的过程。
fetchAndMarkRecordAsActive
方法从数据库中获取一条记录,然后重复该方法本身,如果没有找到记录,它会将超时时间更改为更长的超时时间,大约一个小时。但如果记录仍在获取,则默认超时时间保持在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
。我的错误

这应该让你开始:

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);
  });
}
const ProcessReader=函数(){
这个.longTimeout=3600000;
这一点。超时=600000;
}
ProcessReader.prototype.fetchAndMarkRecordAsActive=函数(){}
ProcessReader.prototype.start=函数(){
const self=这个;
this.fetchAndMarkRecordAsActive(函数)(错误){
如果(错误=='找不到记录'){

self.timeout=self.longTimeout;//@per.eight很高兴为您提供帮助:)