我正在为一个小型的REST库编写测试,该库在request库的顶部实现了OAuth的刷新授权。作为其功能的一部分,它提供了一个重试功能,该功能在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可以stub XHR,但是这似乎是我需要的很多低级工作。
答案 0 :(得分:0)
所以我想出的解决方案是替换整个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);
});
});