I have a function inside one of my angular services that I'd like to be called repeatedly at a regular interval. I'd like to do this using $timeout. It looks something like this:
var interval = 1000; // Or something
var _tick = function () {
$timeout(function () {
doStuff();
_tick();
}, interval);
};
_tick();
I'm stumped on how to unit test this with Jasmine at the moment - How do I do this? If I use $timeout.flush()
then the function calls occur indefinitely. If I use Jasmine's mock clock, $timeout
seems to be unaffected. Basically if I can get this working, I should be good to go:
describe("ANGULAR Manually ticking the Jasmine Mock Clock", function() {
var timerCallback, $timeout;
beforeEach(inject(function($injector) {
$timeout = $injector.get('$timeout');
timerCallback = jasmine.createSpy('timerCallback');
jasmine.Clock.useMock();
}));
it("causes a timeout to be called synchronously", function() {
$timeout(function() {
timerCallback();
}, 100);
expect(timerCallback).not.toHaveBeenCalled();
jasmine.Clock.tick(101);
expect(timerCallback).toHaveBeenCalled();
});
});
These two variations work, but do not help me:
describe("Manually ticking the Jasmine Mock Clock", function() {
var timerCallback;
beforeEach(function() {
timerCallback = jasmine.createSpy('timerCallback');
jasmine.Clock.useMock();
});
it("causes a timeout to be called synchronously", function() {
setTimeout(function() {
timerCallback();
}, 100);
expect(timerCallback).not.toHaveBeenCalled();
jasmine.Clock.tick(101);
expect(timerCallback).toHaveBeenCalled();
});
});
describe("ANGULAR Manually flushing $timeout", function() {
var timerCallback, $timeout;
beforeEach(inject(function($injector) {
$timeout = $injector.get('$timeout');
timerCallback = jasmine.createSpy('timerCallback');
}));
it("causes a timeout to be called synchronously", function() {
$timeout(function() {
timerCallback();
}, 100);
expect(timerCallback).not.toHaveBeenCalled();
$timeout.flush();
expect(timerCallback).toHaveBeenCalled();
});
});
Thanks in advance!
Do not make your test Async by using Jasmine's clock. Instead, use $timeout.flush()
to synchronously maintain the flow of the test. It may be a bit tricky to setup, but once you get it then your tests will be faster and more controlled.
Here's an example of a test that does it using this approach: https://github.com/angular/angular.js/blob/master/test/ngAnimate/animateSpec.js#L618