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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With