如何使用sinon.stub将单元测试写入“请求”节点模块?

时间:2016-02-18 11:40:36

标签: javascript angularjs unit-testing sinon

我的代码中有这个功能:

let request = require("request");
let getDrillDownData = function (userId, query, callback) {

query.id = userId;
let urlQuery = buildUrlFromQuery(query);

request.get({
    url: urlQuery,
    json: true
}, function (error, response, data) {
    if (!error && response.statusCode === 200) {
        return callback(null, calculateExtraData(data));
    } else if (error) {
        return callback(error, null);
    }
});

};

我希望编写一些单元测试,验证当使用正确的参数调用函数时它运行正常, 当出现错误时,它确实返回错误

我写了这个单元测试代码:

describe.only('Server Service Unit Test', function(){
var sinon = require('sinon'),
    rewire = require('rewire');

var reportService;
var reportData = require('./reportData.json');

beforeEach(function(){
    reportService = rewire('../../services/reports.server.service');
});

describe('report methods', function(){
    var reportData;
    var query = { id: "test"};
    var userId = 'testuser';
    var getDrillDownData;

    var request;

    beforeEach(function(){
        getDrillDownData = reportService.__get__('getDrillDownData');
    });

    it ('should get drill down data by userId and query', function(done){
        var getCallback = sinon.stub();

        request = {
            get: sinon.stub().withArgs({
                url: query,
                json: true
            }, getCallback.withArgs("error", {statusCode: 200}, reportData))
        };

        reportService.__set__('request', request);

        getDrillDownData(userId, query, function(err, returnData){
            (err === null).should.eql(true);
            //(getCallback.withArgs(undefined, {statusCode: 200}, reportData).calledOnce).equal(true);
            done();
        });
});

});

但我一直收到错误:

错误:超过2000毫秒的超时。确保在此测试中调用done()回调。

有人可以帮忙吗? 感谢

1 个答案:

答案 0 :(得分:4)

我会直接存根request.get()

describe('report methods', function() {

  // Make `request.get()` a Sinon stub.
  beforeEach(function() {
    sinon.stub(request, 'get');
  });

  // Restore the original function.
  afterEach(function() {
    request.get.restore();
  });

  it ('should get drill down data by userId and query', function(done) {
    // See text.
    request.get.yields(null, { statusCode : 200 }, { foo : 'bar' });

    // Call your function.
    getDrillDownData('userId', {}, function(err, data) {
      ...your test cases here...
      done();
    });
  });
});

使用request.get.yields()(调用Sinon可以在参数列表中找到的第一个函数参数;在这种情况下,它是传递给(error, response, data)的{​​{1}}回调在你的函数中)你可以告诉Sinon用来调用回调的参数。

这样,您可以检查request.get()的回调是否正确处理所有参数。

您也可以使用request.get().withArgs()),但您必须确保正确使用它;否则,如果确切的参数不匹配,Sinon将调用原始request.get.withArgs(...).yields(...)而不是使用存根版本。

相反,我更喜欢使用request.get()在调用之后检查的正确参数。与Mocha集成得更好,因为你可以使用显式断言。