Как проверить в Sinon, если метод повторно вызывается после тайм-аута - PullRequest
1 голос
/ 21 марта 2019

У меня есть метод 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?

Вот следующие тесты, которые я хочу выполнить:

  • Он должен вызывать себя после тайм-аута
  • Он должен вызывать повторно, если найдены записи

Любая помощь приветствуется.

UPDATE:

Измените this.longTimeout на self.longTimeout. Моя ошибка

1 Ответ

1 голос
/ 22 марта 2019

Это должно помочь вам начать:

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);
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...