Reputation: 5977
I have the following controller...
angular.module('jobBoard').controller('JobListController', ['$scope','$window', function($scope, $window){
$scope.keywordPlaceholder = 'What kind of job?';
$scope.locationPlaceholder = 'Where? (city, state or zip)';
$scope.onResize = function(){
if ($window.innerWidth <= 480){
$scope.keywordPlaceholder = 'What?';
$scope.locationPlaceholder = 'Where?';
}
}
angular.element($window).bind('resize', function(){
$scope.onResize();
$scope.$apply();
})
$scope.onResize();
$scope.loadJobs();
}]);
and this is the jasmine test...
describe('JobListController', function(){
var scope, controller;
describe('binding resize to window', function(){
var mockWindow = {
resize: function(){}
}
beforeEach(inject(function($rootScope, $controller){
scope = $rootScope.$new();
$controller('JobListController', { $scope:scope, $window: mockWindow});
}))
it('binds to the resize function', function(){
spyOn(scope, 'onResize');
spyOn(scope, '$apply');
mockWindow.resize();
expect(scope.onResize).toHaveBeenCalled();
expect(scope.$apply).toHaveBeenCalled();
})
})
})
but it's failing on the scope.onResize expectation. I've googled like crazy on how to properly do this but can't seem to find the right answer. Any ideas? Thanks.
Upvotes: 1
Views: 2470
Reputation: 1266
If you want to test that you attach to the event, Angular's $window
service serves that purpose nicely:
describe('JobListController', function(){
var scope, controller;
describe('binding resize to window', function(){
beforeEach(inject(function($rootScope, $controller){
scope = $rootScope.$new();
spyOn($window, 'addEventListener').and.callThrough();
$controller('JobListController', { $scope:scope });
}))
it('binds to the resize function', function() {
expect($window.addEventListener).toHaveBeenCalledWith('resize', scope.onResize);
})
})
})
In your controller, bind using addEventListener
instead:
$window.addEventListener('resize', scope.onResize);
It allow to test when you unbind the event, too:
it('stop listening to window resize', function () {
compileDirective();
spyOn($window, 'removeEventListener');
scope.$destroy();
expect($window.removeEventListener).toHaveBeenCalledWith('resize', scope.onResize);
});
After that, you're free to test your scope.onResize
logic independently.
Pros:
Cons:
Upvotes: 0
Reputation: 19128
To be honest, I've never tried this, so I can't tell you if it's going to work. However - you're confusing calling a function with triggering an event. Your bind
statement binds to an event, not a function call.
From the MDN docs on javascript events, you should be able to do something like this to create an event with the name "resize" and trigger it:
describe('binding resize to window', function(){
// Get a DOM element (there's probably a better way to do this...)
var mockWindow = angular.element('<div>')[0];
// create the event
var resizeEvent = new Event('resize');
beforeEach(inject(function($rootScope, $controller){
scope = $rootScope.$new();
$controller('JobListController', { $scope:scope, $window: mockWindow});
}))
it('binds to the resize function', function(){
spyOn(scope, 'onResize');
spyOn(scope, '$apply');
// call the event.
mockWindow.dispatchEvent(event);
expect(scope.onResize).toHaveBeenCalled();
expect(scope.$apply).toHaveBeenCalled();
})
})
Upvotes: 1