javascript - Angular Jasmine's spyOn has no effect on functions in the factory -
first have controller this:
login.controller.js:
angular.module('app').controller('logincontroller', function($scope,userservice,$location) { $scope.submit = function() { userservice.login(email,password).then(function(data){ if(data.result=='success'){ $location.path('/home'); else{ $scope.loginerror='login failed'; } },function(error){ $scope.loginerror='login failed'; }); };
and factory service:userservice.js
angular.module('app').factory('userservice', function($http,$q,const) { login: function(username, password) { var defer =$q.defer(); $http({ method:'post', url:const.baseurl+'rest/login', data:{ username:username, password:password } }).success(function(data,status,headers,config){ defer.resolve(data); }).error(function(data){ defer.reject(data); }); return defer.promise; },
and jasmine test :
describe('test userservice',function(){ beforeeach(module('app')) var scope,logincontroller,httpbackend; beforeeach(inject(function(_$rootscope_,$controller,_userservice_,_$httpbackend_){ scope = _$rootscope_.$new(); httpbackend = _$httpbackend_; logincontroller = $controller('logincontroller',{ $scope:scope, userservice:_userservice_ }); })); it('when login post return success',function(){ httpbackend.expectpost('rest/login',{ username:'jordan', password:'password' }).respond(200,{result:'success'}); spyon(userservice,'login').and.callthrough(); scope.submit(); httpbackend.flush(); expect(userservice.login).tohavebeencalled(); expect(location.path()).tobe('/home'); }); aftereach(function(){ httpbackend.verifynooutstandingexpectation(); httpbackend.verifynooutstandingrequest(); }); });
and result turns out that:
chrome 43.0.2357 (windows 7 0.0.0) test userservice when login post retu rn success failed expected spy login have been called. @ object.<anonymous> (c:/users/ibm_admin/desk/workspace/waterfundwe b/webcontent/test/unit/userservice.js:28:29)
but sure login() function invoked,how comes this
first of all, i've refactored logincontroller
, userservice
:
//i created const factory , returns empty string baseurl, //because don't know what's logic inside factory in code. angular.module('app').factory('const', function() { return { baseurl: '' }; }); angular.module('app').factory('userservice', function($http, $q, const) { //userservice should return object login function. //you've shown code factory incorrect syntax. return { login: function (username, password) { var defer = $q.defer(); $http({ method: 'post', url: const.baseurl + 'rest/login', data: { username: username, password: password } }).success(function (data, status, headers, config) { defer.resolve(data); }).error(function (data) { defer.reject(data); }); return defer.promise; } }; }); angular.module('app').controller('logincontroller', function($scope, userservice, $location) { //here have add parameters $scope.submit function, //because you're going use while calling userservice.login function $scope.submit = function (email, password) { userservice.login(email, password).then( function (data) { if (data.result == 'success') { $location.path('/home'); } else { $scope.loginerror = 'login failed'; } }, function (error) { $scope.loginerror = 'login failed'; }); }; });
after refactoring i've found syntax errors in tests. i'm showing whole code comments , fixes.
describe('test userservice',function() { var scope, logincontroller, httpbackend, userservice, //you should create variable userservice work further (creating spies , on) location; //you need variable $location service check current path in test beforeeach(inject(function(_$rootscope_, $controller, userservice, _$httpbackend_, _$location_) { scope = _$rootscope_.$new(); httpbackend = _$httpbackend_; ////don't forget initialize 'new' variables location = _$location_; userservice = userservice; logincontroller = $controller('logincontroller', { $scope:scope, userservice: userservice, $location: location //pass $location service logincontroller }); })); it('when login post return success',function(){ httpbackend.expectpost('rest/login',{ username:'jordan', password:'password' }).respond(200,{result:'success'}); spyon(userservice, 'login').and.callthrough(); //here pass parameters, needed login function. //you expect post request rest/login url sent 'jordan' username , 'password' password. //so, pass $scope.submit function scope.submit('jordan', 'password'); httpbackend.flush(); expect(userservice.login).tohavebeencalled(); expect(location.path()).tobe('/home'); }); aftereach(function(){ httpbackend.verifynooutstandingexpectation(); httpbackend.verifynooutstandingrequest(); }); });
now test passes.
if have questions or doesn't work you, let me know.
Comments
Post a Comment