Patrick Lec Patrick Lec - 11 days ago 6
AngularJS Question

Unable to Unit Test an Angular Controller with service mocked

I'm starting with angularJs and I'm facing an issue when trying to unit test a controller that have a dependency to a service. The application worked as expected but not the unit test.
I obtain the following error with Jasmine test:
Error: [$injector:modulerr] Failed to instantiate module ghhweb.register due to:
Error: [$injector:unpr] Unknown provider: $stateProvider

My code for the module:

var registerModule = angular.module('ghhweb.register',[]);

registerModule.config(function($stateProvider, $locationProvider){
var registerState = {
name: 'register',
url: '/register',
controller: 'RegisterController',
templateUrl: 'modules/register/views/register.html'
};

$stateProvider.state(registerState);
});


My code for the Controller:

var registerController = angular.module('ghhweb.register.controller',[]);

registerController.controller('RegisterController', ['$scope',
'userRestService', function($scope, userRestService){
$scope.callCheckExistingMail = function(){
$scope.userEmail = userRestService.checkExistingMail($scope.userEmail);
};
}]);


My specification code :

describe('controller register module unit tests', function(){
describe('check user service implementation', function(){

beforeEach(module('ghhweb.register'));

it('should call checkExistinMail in userRestService', inject(function(
$rootScope, $controller){
// make a userRestService
var userRestService = {
checkExistingMail: function() {}
};

spyOn(userRestService, "checkExistingMail");

controller('RegisterController', {$scope: scope,
userRestService: userRestService });

expect(userRestService.checkExistingMail).toHaveBeenCalled();
}));

});

});


I have tryed lot of tutos and check lot of posts like (angular-unit-test-controllers-mocking-service-inside-controller or injecting-a-mock-into-an-angularjs-service)

I suppose I have a configuration issue somewhere but I'm unable to solve it.

Is someOne have an idea?

Answer

I suppose the previous specification is not allowed with my current librairies versions. I'm using:

"devDependencies": {
"bower": "^1.8.0",
"http-server": "^0.9.0",
"jasmine-core": "^2.4.1",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-firefox-launcher": "^1.0.0",
"karma-jasmine": "^1.0.2",
"phantomjs": "^2.1.7",
"protractor": "^4.0.9"

after further investigation I obtain the following specification:

describe('controller register module unit tests implementation', function(){

var $controller;
var $scope;
var userRestService;

beforeEach(module('ghhweb.register.controller', function($provide){
    userRestService = jasmine.createSpyObj('userRestService'
        , ['checkExistingMail']);

    userRestService.checkExistingMail.and.returnValue(0);

    $provide.value('userRestService', userRestService);
}));


beforeEach(inject(function(_$controller_, $rootScope,_userRestService_){
    $scope = $rootScope.$new();
    userRestService = _userRestService_;
    $controller = _$controller_('RegisterController', {
        $scope: $scope,
        userRestService: userRestService
    });
    $scope.callCheckExistingMail();
}));

it('should call userRestService', function(){
    expect(userRestService.checkExistingMail).toHaveBeenCalled();
});

});

and it works