Я пишу тесты для небольшой библиотеки 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 , но это похоже на много усилий низкого уровня для того, что я хочу.