Published: March 06 2015

AngularJS - Unit Testing code that uses $timeout

While working through writing unit tests today I reached some code in a controller that displays an alert message and then hides it after five seconds with the angular $timeout service, here's a cut down version of the controller:

    .controller('myController', myController);

myController.$inject = ['$timeout'];

function myController($timeout) {
    var vm = this;

    vm.alertVisible = false;
    vm.showAlert = showAlert;

    function showAlert(){
        // show alert
        vm.alertVisible = true;

        // hide alert after 5 seconds
            vm.alertVisible = false;
        }, 5000);


Sinon.JS Fake Timer doesn't work with AngularJS $timeout

I'm using Sinon.JS in my unit tests so I tried using a fake timer to artificially tick the clock 5000ms but this didn't work, and after some further testing I found that the Sinon fake timer works with the native javascript setTimeout function but not with the AngularJS $timeout service.


Solution - Use $timeout.flush()

The solution turned out to be much simpler than setting up fake timers, I just needed to flush the queue of the $timeout service by calling $timeout.flush(), here's the snippet from the unit tests:

describe('controller: myController', function(){
    describe('showAlert', function(){
            // Arrange
            vm.alertVisible = false;

            // Act
            vm.showAlert('test alert message');

        it('should show the alert', function(){
            // Assert

        it('should hide the alert after 5 seconds', function(){
            // Act - flush $timeout queue to fire off deferred function

            // Assert


Need Some AngularJS Help?

Search fiverr for freelance AngularJS developers.

Follow me for updates

On Twitter or RSS.

When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Supported by