UPDATE:. The correct method for bullying setInterval in an angular 1.2+ application is to use the angular $interval . Using the $interval service provides a number of benefits, but the $interval.flush() method is most useful in this situation. When writing tests, $interval provides the .flush() method, which allows you to make fun of the JS clock.
app.directive('shuffleBlocks', function($timeout, $interval){ return { link: function(sco,ele,att){ if (itemCnt <= 1) return; function triggerEvent(){ ... } ele.bind('click', triggerEvent); $interval(triggerEvent, 5000); } } });
and then in unit test:
var elem = '<div shuffle-blocks><div>'; elem = mockCompile(elem)(rootScope.$new()); $interval.flush(5000);
Hope this helps anyone looking for this answer in the future. I will leave my previous answer to those who are still using 1.1X.
Previous answer: According to jasmine docs , you should simply use the jasmine.Clock.useMock() function to mock typical javascript watches and manually work your way through the interval. Since angular just wraps the setTimeout built-in function, I'm pretty sure this should let this work, although I haven't tested it to be sure.
Jasmine docs for version 1.3 are here . Here is a sample code demonstrating how it works.
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(); });
The only problem I see is that your triggerEvent() function is local to your link function, so I donβt know how you can get to it to mock it. But, hopefully, this indicates that you are in the right direction. If not, sorry, I tried.
UPDATE: The syntax for watch bullying has changed in Jasmine 2.0 . If you are using 2.0, see Updated documents here .