javascript - How do I mock a service that returns promise in Angularjs Jasmine unit test? -
i have myservice uses myotherservice, makes remote call, returning promise:
angular.module('app.myservice', ['app.myotherservice']) .factory('myservice', [myotherservice, function(myotherservice) { function makeremotecall() { return myotherservice.makeremotecallreturningpromise(); } return { makeremotecall: makeremotecall }; } ])
to make unit test myservice
need mock myotherservice
, such makeremotecallreturningpromise()
method returns promise. how it:
describe('testing remote call returning promise', function() { var myservice; var myotherservicemock = {}; beforeeach(module('app.myservice')); // have inject mock when calling module(), // , module() should come before inject() beforeeach(module(function ($provide) { $provide.value('myotherservice', myotherservicemock); })); // however, in order construct mock // need $q, can give me promise beforeeach(inject( function(_myservice_, $q){ myservice = _myservice_; myotherservicemock = { makeremotecallreturningpromise: function() { var deferred = $q.defer(); deferred.resolve('remote call result'); return deferred.promise; } }; } // here value of myotherservicemock not // updated, , still {} it('can remote call', inject(function() { myservice.makeremotecall() // error: makeremotecall() not defined on {} .then(function() { console.log('success'); }); }));
as can see above, definition of mock depends on $q
, have load using inject()
. furthermore, injecting mock should happening in module()
, should coming before inject()
. however, value mock not updated once change it.
what proper way this?
i'm not sure why way did doesn't work, spyon
function. this:
describe('testing remote call returning promise', function() { var myservice; beforeeach(module('app.myservice')); beforeeach(inject( function(_myservice_, myotherservice, $q){ myservice = _myservice_; spyon(myotherservice, "makeremotecallreturningpromise").and.callfake(function() { var deferred = $q.defer(); deferred.resolve('remote call result'); return deferred.promise; }); } it('can remote call', inject(function() { myservice.makeremotecall() .then(function() { console.log('success'); }); }));
also remember need make $digest
call then
function called. see testing section of $q documentation.
------edit------
after looking closer @ you're doing, think see problem in code. in beforeeach
, you're setting myotherservicemock
whole new object. $provide
never see reference. need update existing reference:
beforeeach(inject( function(_myservice_, $q){ myservice = _myservice_; myotherservicemock.makeremotecallreturningpromise = function() { var deferred = $q.defer(); deferred.resolve('remote call result'); return deferred.promise; }; }
Comments
Post a Comment