If you were to run console.log(Object.keys(this.$timeout));
in your test suite, you will see the following output;
LOG: ['identity', 'isSpy', 'plan', 'mostRecentCall', 'argsForCall', 'calls', 'andCallThrough', 'andReturn', 'andThrow', 'andCallFake', 'reset', 'wasCalled', 'callCount', 'baseObj', 'methodName', 'originalValue']
$timeout
is a function which AngularJS is also decorating—since functions are objects—with a cancel
method. Because this isn't that common a thing to do, Jasmine replaces rather than augments $timeout
with it's spying implementation - clobbering $timeout.cancel
.
A workaround for this is to put the cancel
spy back again after $timeout
has been overwritten by Jasmine's $timeout
spy, as follows;
describe('<whatever>', function() {
beforeEach(function() {
spyOn(this.$timeout, 'cancel').andCallThrough();
var $timeout_cancel = this.$timeout.cancel;
spyOn(this, '$timeout').andCallThrough();
this.$timeout.cancel = $timeout_cancel;
this.createController();
});
it('should <whatever>', function() {
expect(this.$timeout).toHaveBeenCalled();
expect(this.$timeout.cancel).toHaveBeenCalled();
});
});