I would like to unit test an Angular.js $timeout to check that it has been called with the correct duration/delay value.
The assertion would look something like this:
expect($timeout).toHaveBeenCalledWith(n);
My Angular code looks roughly like the following:
$timeout(function() {
// do something
}, attrs.timeout || 30000);
I want to ensure that without an override (attrs.timeout) it is called with 30000 and with the override it is called with that override.
I have tried a decorator like this:
// from: http://stackoverflow.com/a/21536245/633056
beforeEach(module(function($provide) {
$provide.decorator('$timeout', function($delegate) {
return jasmine.createSpy($delegate);
});
}));
Plus several other methods but I cannot seem to get it to work.
I am using Angular 1.3.20, Jasmine 2.3.4
Any suggestions gratefully received.
You can try create a mock for the timeout and set expectation on the spy. For checking the first argument you can use the matcher jasmine.any(Function) and second argument with expected delay.
Example:
describe('Ctrl', function() {
beforeEach(module('test-app'));
var ctrl, timeout;
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
//Create Spy
timeout = jasmine.createSpy('$timeout');
ctrl = $controller('loadingCtr', {
'$timeout': timeout
});
$rootScope.$digest();
}));
//Your expectations
it('should call timeout with passed in delay', function() {
ctrl.callTimeout(1000);
expect(timeout).toHaveBeenCalledWith(jasmine.any(Function), 1000);
});
it('should call timeout with default delay', function() {
ctrl.callTimeout();
expect(timeout).toHaveBeenCalledWith(jasmine.any(Function), 30000);
});
});
Demo
If it is a directive just override timeout with your spy.
var dir,
timeout = jasmine.createSpy('$timeout'), scope;
beforeEach(module('test-app', function ($provide) {
$provide.value('$timeout', timeout);
}));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope.$new();
$compile('<test-timeout timeout="6000"></test-timeout>')(scope);
scope.$apply();
}));
it('should call timeout with passed in delay', function() {
expect(timeout).toHaveBeenCalledWith(jasmine.any(Function), 6000);
});
Demo
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