Заполнение запроса по всему проекту - PullRequest
0 голосов
/ 01 марта 2019

Я пишу тесты для небольшой библиотеки REST, которая реализует грант обновления OAuth поверх библиотеки request .В рамках своей функциональности он предоставляет функцию повтора, которая имеет что-то вроде этого в rest.js:

const auth = require('./auth');
const request = require('request');

function retry(headers, responseHandler) {
  headers.auth.bearer = auth.getToken();
  request(headers, function(err, resp) {
    if (resp.error && resp.error == 'invalid_token') {
      return auth.renew(function(e, r) { retry(headers, responseHandler); });
    }
    // handle happy case
  });
});

Что auth.renew делает, отправляет провайдеру токенов информацию в headers и внутреннеизвестный токен обновления.Важным моментом является то, что он делает это с помощью request.post, передавая обработчик рекурсивных событий в библиотеку запросов.

Естественно, когда я проверяю это, я не хочу исходящих HTTP-вызовов.Поэтому я использую sinon, чтобы заглушить их:

const requestStub = sinon.stub(),
    rest = proxyquire('./rest', { 'request': requestStub }),
    authFail = { error: 'invalid_token' },
    authSuccess = { token: '123' };

describe('#retry', () => {
  it('calls retry twice on failed auth', () => {
    requestStub.yields(null, authFail);
    requestStub.post = sinon.stub().yields(null, authSuccess);

    retry({}, () => {});
    sinon.assert.calledTwice(requestStub);
  });
});

Проблема в том, что auth.renew счастливо переходит к require('request') самостоятельно и, таким образом, никогда не видит мою заглушку.Итак, я думаю, мой вопрос звучит так: как мне заставить auth использовать мою заглушку request вместо своей?

Я знаю, что Sinon может заглушка XHR , но это похоже на много усилий низкого уровня для того, что я хочу.

1 Ответ

0 голосов
/ 04 марта 2019

Таким образом, решение, которое я придумал, состояло в том, чтобы заменить весь метод auth.renew, чтобы все выглядело так:

const requestStub = sinon.stub(),
    rest = proxyquire('./rest', { 'request': requestStub, 
      './auth': { 
        renew: function(callback) {
          requestStub.yields(null, authSuccess);
          callback();
        }
    }),
    authFail = { error: 'invalid_token' },
    authSuccess = { token: '123' };

describe('#retry', () => {
  it('calls retry twice on failed auth', () => {
    requestStub.yields(null, authFail);

    retry({}, () => {});
    sinon.assert.calledTwice(requestStub);
  });
});
...