javascript - How stub a global dependency's new instance method in nodejs with sinon.js -
sorry confusing title, have no idea how better describe it. let's see code:
var client = require('some-external-lib').createclient('config string'); //constructor function myclass(){ } myclass.prototype.dosomething = function(a,b){ client.dowork(a+b); } myclass.prototype.dosomethingelse = function(c,d){ client.dowork(c*d); } module.exports = new myclass();
test:
var sinon = require('sinon'); var myclass = requre('./myclass'); var client = require('some-external-lib').createclient('config string'); describe('dosomething method', function() { it('should call client.dowork()',function(){ var stub = sinon.stub(client,'dowork'); myclass.dosomething(); assert(stub.calledonce); //not working! returns false }) })
i working if .createclient('xxx') called inside each method instead, stub client with:
var client = require('some-external-lib'); sinon.stub(client, 'createclient').returns({dowork:function(){})
but feels wrong init client everytime method each being called.
is there better way unit test code above?
new: have created minimal working demo demonstrate mean: https://github.com/markni/stackoverflow30825202 (simply npm install && npm test
, watch test fail.) question seeks solution make test pass without changing main code.
the problem arises @ place of test definition. fact in node.js rather difficult dependency injection. while researching in regard of answer came across interesting article di implemented via custom loadmodule
function. rather sophisticated solution, maybe come think worth mentioning. besides di gives benefit of access private variables , functions of tested module.
to solve direct problem described in question can stub client creation method of some-external-lib
module.
var sinon = require('sinon'); //instantiate some-external-lib var client = require('some-external-lib'); //stub function of client create mocked client sinon.stub(client, 'createclient').returns({dowork:function(){}) //due singleton nature of modules `require('some-external-lib')` inside //myclass module same client have stubbed var myclass = require('./myclass');//inside stubbed version of createclient //will called. //it return mock instead of real client
however, if test gets more complicated , mocked client gets state have manually take care of resetting state between different unit tests. tests should independent of order launched in. important reason reset in beforeeach
section
Comments
Post a Comment