在整个项目中存根请求

时间:2019-03-01 14:09:33

标签: javascript unit-testing requirejs sinon proxyquire

我正在为一个小型的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,但是这似乎是我需要的很多低级工作。

1 个答案:

答案 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);
  });
});