Jasmine controller testing, expected spy to have been called

匿名 (未验证) 提交于 2019-12-03 08:44:33

问题:

I have a method defined in AngularJS controller which is called on initialization. I want to test it using Jasmine ("jasmine-core": "^2.3.4", "karma": "^0.12.37"). I follow some tutorials on the Internet and StackOverflow questions, but I cannot find the right answer. Please take a look at this code:

Controller usersAddUserController:

(function () {     'use strict';      angular.module('app.users.addUser')         .controller('usersAddUserController', ['$scope', 'usersAddUserService', function ($scope, usersAddUserService) {              usersAddUserService.getCountryPhoneCodes().then(function (phoneCodes) {                 $scope.phoneCodes = phoneCodes;             });          }]); }()); 

Jasmine test:

(function () {      'use strict';      describe('usersAddUserControllerUnitTest', function () {         var scope, deferred, objectUnderTest, mockedAddUserService;          beforeEach(module('app'));          beforeEach(inject(function ($rootScope, $q, $controller) {             scope = $rootScope.$new();              function emptyPromise() {                 deferred = $q.defer();                 return deferred.promise;             }              mockedAddUserService = {                 getCountryPhoneCodes: emptyPromise             };              objectUnderTest = $controller('usersAddUserController', {                 $scope: scope,                 usersAddUserService: mockedAddUserService             });         }));          it('should call getCountryPhoneCodes method on init', function () {             //when                         spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough();              deferred.resolve();              scope.$root.$digest();              //then             expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled();         });      }); }()); 

After running the tests, the error message is:

PhantomJS 1.9.8 (Windows 7 0.0.0) usersAddUserControllerUnitTest should call getCountryPhoneCodes method on init FAILED

    Expected spy getCountryPhoneCodes to have been called. 

I obviously missing something, but I cannot figure out what it is. Any help will be appreciated.

回答1:

You are spying on the mock after it has been passed into the instantiated controller.

Try this:

describe('usersAddUserControllerUnitTest', function () {     var scope, deferred, objectUnderTest, mockedAddUserService, $controller;      beforeEach(module('app'));      beforeEach(inject(function ($rootScope, $q, _$controller_) {         scope = $rootScope.$new();          function emptyPromise() {             deferred = $q.defer();             return deferred.promise;         }          mockedAddUserService = {             getCountryPhoneCodes: emptyPromise         };          $controller = _$controller_;     }));      function makeController() {             objectUnderTest = $controller('usersAddUserController', {             $scope: scope,             usersAddUserService: mockedAddUserService         });     }      it('should call getCountryPhoneCodes method on init', function () {         //when          spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough();         makeController();          deferred.resolve();          scope.$root.$digest();          //then         expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled();     });  }); 

EDIT Thanks @juunas for noticing the bug in my solution



回答2:

You can provide the mock like this:

mockedAddUserService = {     getCountryPhoneCodes: emptyPromise };   beforeEach(function () {     module(function ($provide) {         $provide.value('usersAddUserService', mockedAddUserService);     }); }); 

EDIT:

The code should look (as i cannot test it) like this:

(function () {     'use strict';      describe('usersAddUserControllerUnitTest', function () {                 beforeEach(module('app'));          var emptyPromise = function() {             var deferred = $q.defer();             return deferred.promise;         }          var mockedAddUserService = {             getCountryPhoneCodes: emptyPromise         };          beforeEach(function () {             module(function ($provide) {                 $provide.value('usersAddUserService', mockedAddUserService);             });         });          var scope;         beforeEach(inject(function ($rootScope, $q, $controller) {             scope = $rootScope.$new();             $controller('usersAddUserController', {                 $scope: scope             });         }));          it('should call getCountryPhoneCodes method on init', function () {             spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough();              scope.$root.$digest();              expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled();         });      }); }()); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!