Published:

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:

angular
    .app('app')
    .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
        $timeout(function(){
            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(){
        beforeEach(function(){
            // Arrange
            vm.alertVisible = false;

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

        it('should show the alert', function(){
            // Assert
            assert.isTrue(vm.alertVisible);
        });

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

            // Assert
            assert.isFalse(vm.alertVisible);
        });
    })
});

 


Subscribe or Follow Me For Updates

Subscribe to my YouTube channel or follow me on Twitter, Facebook or GitHub to be notified when I post new content.

Other than coding...

I'm currently attempting to travel around Australia by motorcycle with my wife Tina on a pair of Royal Enfield Himalayans. You can follow our adventures on YouTube, Instagram and Facebook.


Need Some AngularJS Help?

Search fiverr to find help quickly from experienced AngularJS developers.



Supported by