angularjs - Angular Unit Testing - Mocking methods/closures in same service -


i'm trying unit test angular service using sinonjs, have been running issue , hoping possibly shed light on why occurring. have reconstructed current project illustrate problem @ hand.

i have provided demo

i have service, peopleservice:

(function (){    angular.module('myapp')     .factory('peopleservice', peopleservice);      peopleservice.$inject = ['$q'];      function peopleservice ($q){       var people = ['homer', 'marge', 'bart', 'lisa', 'maggie'];        // in actual project, makes http request       function getfamily () {          return people;       }        function getadults (){         var family = getfamily();         return family.filter(function (person){           return person === 'homer' || person === 'marge';         });       }        return {         getfamily: getfamily,         getadults: getadults       }     }  }()); 

in service, method getadults uses getfamily, filters results, , returns data.

in unit test, trying mock getfamily , see if method being called. problem presents itself...

first thing tried stubbing out method , overwriting current method, so:

beforeeach(function (){   module('myapp');    inject(function (_peopleservice_){     peopleservice = _peopleservice_; // service     sinon.stub(peopleservice, 'getfamily'); // stub   }); }); 

i go test whether getadults calls getfamily method:

it('getadults should call "getfamily" once', function(){      peopleservice.getadults();      expect(peopleservice.getfamily.calledonce).tobe(true); }); 

the test fails , stubbed method not called...

i debug , find out although function has in fact changed: enter image description here

the service still holds reference (closure) method used when service created:

enter image description here

my initial thought didn't stub method correctly. attempted overwriting method using $provide ($provide.value) $injector decorator , ended getting same result (closure held onto original method).

a solution use this:

 function getadults (){     var family = this.getfamily(); // <-- using this.getfamily reference mock     return family.filter(function (person){       return person === 'homer' || person === 'marge';     });   } 

however, not understand why have this.

in short, know:

  • how mock method in same service without having use this
  • how mock out closure variable in unit test

thank time.

when stub method on object, property of object overriden, not original function references.

take, example, code:

function myfunction () {}; var myobj = { prop: myfunction };  myobj.prop === myfunction; // true myobj.prop = 'changed';  typeof myfunction === 'function'; // true myobj.prop === myfunction; // false 

changing myobj.prop did not change original function, myfunction still exists in own right. myobj.prop, however, has lost reference myfunction. if in sinon world, stubbing changed reference of myobj.prop stub object.

this why when testing code in service calls function in same service, code needs reference same object returned service. if want avoid using this keyword everywhere, can structure service so:

angular.module('myapp')   .factory('peopleservice', peopleservice);  peopleservice.$inject = ['$q'];  function peopleservice ($q){   var service = {     getfamily: getfamily,     getadults: getadults   };    return service;    function getfamily () {      // ...   }    function getadults (){     var family = service.getfamily(); // <-- reference service.getfamily()     // ...   } } 

Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -