Reputation: 37318
I try to unit test an angularJS controller with Kara/Sinon/Jasmine. The controller listens to state changes from angular-ui-router to call a service.
I stubbed the service method (update) using sinon and i use $broadcast to throw the event in the tests. I use $apply to fire the event.
However, it seems the controller does not seem to react.
I try to check for teh sinon stubbed method and i also use console.log to see weather or not the controller reacts - but it does not. It does in the manual browser test, so i guess it is my test that needs to be fixed (should be the other way round, i know).
What am i doing wrong here?
the karma test specs:
'use strict';
describe('controllers', function() {
beforeEach(module('myApp.controllers'));
beforeEach(module('myApp.services'));
beforeEach(module('ui.router'));
describe('myAppController', function() {
var scope, ctrl;
beforeEach(inject(function(
$rootScope, $controller, $injector,ParamsHelper) {
scope = $rootScope.$new();
scope.ParamsHelperStub = sinon.stub(ParamsHelper, 'update');
ctrl = $controller('myAppController', {
$scope: scope,
ParamsHelper: scope.ParamsHelperStub
});
}));
it('should use ParamsHelper if is deepLink', function() {
var event = {};
var toState = {name:'regions'};
var toParams = ['test'];
scope.AppSettingsStub.state.isDeepLink = true;
scope.$broadcast("$stateChangeStart", event, toState, toParams);
scope.$apply();
expect(scope.ParamsHelperStub.calledWith(['test'])).toBeTruthy();
});
});
});
From the controller:
...
rootScope.$on('$stateChangeStart',
function(event, toState, toParams) {
console.log('VibeController: $stateChangeStart Event catched');
ParamsHelper.update(toParams);
...
Upvotes: 2
Views: 1961
Reputation: 37318
The problem was in the scope. To fire an event that can be recognized by the controller i need to fire it in the rootScope context.
I added the rootScope in the initial injection and then edited the broadcasting command accordingly:
describe('myAppController', function() {
var scope, ctrl, rootScope;
beforeEach(inject(function(
$rootScope, $controller, $injector, ParamsHelper) {
rootScope = $rootScope;
...
rootCope.$broadcast("$stateChangeStart", event, toState, toParams);
Upvotes: 3