Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spy on setTimeout and clearTimeout in Karma and Jasmine

I cannot seem to be able to spy on setTimeout and clearTimeout in my Jasmine tests, which are being run through Karma.

I have tried variations on all of this

spyOn(window, 'setTimeout').and.callFake(()=>{});
spyOn(global, 'setTimeout').and.callFake(()=>{});
spyOn(window, 'clearTimeout').and.callThrough();

clock = jasmine.clock();
clock.install();
spyOn(clock, 'setTimeout').and.callThrough();

runMyCode();

expect(window.setTimeout).toHaveBeenCalled(); // no
expect(global.setTimeout).toHaveBeenCalled(); // nope
expect(window.clearTimeout).toHaveBeenCalled(); // no again
expect(clock.setTimeout).toHaveBeenCalled(); // and no

In every case, I can confirm that setTimeout and clearTimeout have been invoked in runMyCode, but instead I always get Expected spy setTimeout to have been called.

For window, clearly this is because the test and the runner (the Karma window) are in different frames (so why should I expect anything different). But because of this, I can't see any way to confirm that these global functions have been invoked.

I know that I can use jasmine.clock() to confirm that timeout/interval callbacks have been invoked, but it looks like I can't watch setTimeout itself. And confirming that clearTimeout has been called simply isn't possible.

At this point, the only thing I can think of is to add a separate layer of abstraction to wrap setTimeout and clearTimeout or to inject the functions as dependencies, which I've done before, but I think is weird.

like image 807
Andrew Avatar asked Jan 29 '16 08:01

Andrew


2 Answers

I was able to get it to work like this:

spyOn(window, 'setTimeout');
runMyCode();
expect(setTimeout).toHaveBeenCalled();

Just remove the 'window' object from the setTimeout call.

like image 127
Bobby Avatar answered Oct 18 '22 00:10

Bobby


For those looking for a Jest solution, it has dedicated fake timer functions (which are also spyable).

like image 41
Piotr Jaworski Avatar answered Oct 18 '22 02:10

Piotr Jaworski