Search code examples
unit-testingangularjsjasminespy

How do you spy on AngularJS's $timeout with Jasmine?


I am trying to spy on $timeout so that I can verify that it has not been called. Specifically, my production code (see below) calls $timeout as a function, not an object:

$timeout(function() { ... })

and not

$timeout.cancel() // for instance

Jasmine, however, requires an object to be spied upon, like this:

spyOn(someObject, '$timeout')

I don't know what 'someObject' would be though.

I am using Angular mocks, if that makes any difference.

Edit: The relevant production code I'm trying to test looks like this:

EventHandler.prototype._updateDurationInOneSecondOn = function (call) {
    var _this = this;
    var _updateDurationPromise = this._$timeout(function () {
            call.duration = new Date().getTime() - call.startTime;
            _this._updateDurationInOneSecondOn(call);
        }, 1000);
    // ... more irrelevant code
}

In the specific test scenario I am trying to assert that $timeout was never called.

Edit 2: Specified clearly that I am using $timeout as a function, not an object.


Solution

  • In angular $timeout is a service that executes/calls a function. The request to "spy" $timeout is a bit odd being the case that what it is doing is executing X function in Y given time. What I would do to spy this services is to "mock" the timeout function and inject it in your controller something like:

     it('shouldvalidate time',inject(function($window, $timeout){
    
            function timeout(fn, delay, invokeApply) {
                console.log('spy timeout invocation here');
                $window.setTimeout(fn,delay);
            }
    
    //instead of injecting $timeout in the controller you can inject the mock version timeout
            createController(timeout);
    
    // inside your controller|service|directive everything stays the same 
    /*      $timeout(function(){
               console.log('hello world');
                x = true;
            },100); */
            var x = false; //some variable or action to wait for
    
            waitsFor(function(){
                return x;
            },"timeout",200);
    
    ...