简体   繁体   中英

How to stub chained functions using sinon.js

For writing my test I am using mocha framework in a stack with Chai as an assertion library and Sinon.JS for mocks, stubs and spies. Assuming that I have some chained functions, for example:

request
    .get(url)
    .on('error', (error) => {
        console.log(error);
    })
    .on('response', (res) => {
        console.log(res);
    })
    .pipe(fs.createWriteStream('log.txt'));

What is the best way to stub them, considering that I would like to assert their calling with needed arguments?

Such a construction:

requestStub = {
    get: function() {
        return this;
    },
    on:  function() {
       return this;
    }
    //...
};

Would not permit me to assert those methods like:

expect(requestStub.get).to.be.called;
expect(requestStub.on).to.be.calledWith('a', 'b');

The usage of returns() method of a stub:

requestStub = {
        get: sinon.stub().returns(this),
        on:  sinon.stub().returns(this),
    };

Will not return the object, and cause an error:

TypeError: Cannot call method 'on' of undefined

Tell me please, how can I stub chained functions?

The first way is correct for stubbing your request object, however, if you want to test if the methods were called and/or check what arguments were used when calling them, maybe you'll have an easier time using spies instead. Here's the sinon-chai documentation on how to use them

'use strict';
var proxyquire = require('proxyquire').noPreserveCache();

var chai = require('chai');

// Load Chai assertions
var expect = chai.expect;
var assert = chai.assert;
chai.should();
var sinon = require('sinon');
chai.use(require('sinon-chai'));


var routerStub = {
   get: function() {
        return this;
    },
    on:  function() {
        return this;
    }
}
var routerGetSpy;
var configStub={
    API:"http://test:9000"
}
var helperStub={

}
var reqStub = {
    url:"/languages",
    pipe: function(){
            return resStub
        }
}
var resStub={
    pipe: sinon.spy()
}
// require the index with our stubbed out modules
var Service = proxyquire('../../../src/gamehub/index', {
            'request': routerStub,
            '../config': configStub,
            '../utils/helper': helperStub
        });

describe('XXXX Servie API Router:', function() {

  describe('GET /api/yy/* will make request to yy service defined in config as "<service host>/api/* "' , function() {

    it('should verify that posts routes to post.controller.allPosts', function() {
        var get = sinon.spy(routerStub, 'get')
        Service(reqStub);
        expect(get.withArgs("http://test:9000/api/languages")).to.have.been.calledOnce;
    });
  });

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM