I'm new at unit testing of Angular with Jasmine, I have been struggling with this code for a few hours, I went through a lot articles and answers here, ,but, I can't find the solution.
The services are mocks as you can see. The problem is that, the code below throws that error it does not find the authenticationService variable. However, based on the info I collected today, it should be injected into the "it" method.
If I rewrite the code and the necessary stuff is injected at the "it" method than it is works. But, it is ugly and not the way which should be followed, because it causes boilerplate code.
What I'm doing wrong?
I tried to move the inject(function ($rootScope, $controller) block to over creating the mocks but it didn't help, and later I understood that there is a proper order in injecting should be kept in mind. So I put them back in the nested describe block.
The purpose of the test is check whether the authenticationService.authenticate() is called when the event:auth-loginRequired is fired. I'm not sure whether the assert part of the code is correct. I'm going to work on it once the issue I described above is fixed.
describe('dilibShell module speccifications', function ()
{
var $location, $rootScope, scope, AuthenticationService, AuthService, Common, ShellController;
beforeEach(module('dilibShell'));
beforeEach(function ()
{
AuthenticationService = {
authenticate: function (user)
{
return 'user';
}
}
AuthService = {
loginConfirmed: function () { }
}
Common = {
activateController: function () { },
logger: {
getLogFn: function () { }
}
}
module(function ($provide)
{
$provide.value('authenticationService', AuthenticationService);
});
module(function ($provide)
{
$provide.value('authService', AuthService);
});
module(function ($provide)
{
$provide.value('common', Common);
});
});
describe('shellController Specification', function ()
{ beforeEach(function ()
{
inject(function ($rootScope, $controller)
{
rootScope = $rootScope;
scope = $rootScope.$new();
ShellController = $controller('shellController', {
$scope: scope
});
});
});
it('When event:auth-loginRequired is caught then authenticationService.authenticate must be invoked.',
(function ()
{
expect(authenticationService.authenticate()).toBe('user');
//arrange
//spyOn(authenticationService, 'authenticate');
scope.$digest();
//act
rootScope.$broadcast('event:auth-loginRequired');
//assert
expect(authenticationService.authenticate).toHaveBeenCalledWith();
}));
});
});
Update:
Based on the answers here I modified my code and the it block looks like below and it is working fine, not counting another error in the code, but that one is over this scope.
So, my question is that it is inevitable that, in case of injecting services mocks, I have to call inject in the particular it blocks?
it('When event:auth-loginRequired is caught then authenticationService.authenticate must be invoked.',
(inject(function (authenticationService)
{
expect(authenticationService.authenticate()).toBe('user');
//arrange
spyOn(authenticationService, 'authenticate');
//scope.$digest();
//act
rootScope.$broadcast('event:auth-loginRequired');
//assert
expect(authenticationService.authenticate).toHaveBeenCalledWith();
})));