65.9K
CodeProject is changing. Read more.
Home

Mock the window.setTimeout in a Jasmine Test to Avoid Waiting

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1 vote)

Aug 22, 2014

CPOL
viewsIcon

8061

Mock the window.setTimeout in a Jasmine test to avoid waiting

Originally posted on http://geekswithblogs.net/Aligned/archive/2014/08/21/mock-the-window.settimeout-in-a-jasmine-test-to-avoid-waiting.aspx.

Jasmine has a clock mocking feature, but I was unable to make it work in a function that I’m calling and want to test. The example only shows using clock for a setTimeout in the spec tests and I couldn’t find a good example. Here is my current and slightly limited approach.

If we have a method we want to test:

var test = function(){
        var self = this;
        self.timeoutWasCalled = false;
        self.testWithTimeout = function(){
           window.setTimeout(function(){
             self.timeoutWasCalled = true;
           }, 6000);
        };
};

Here’s my testing code:

var realWindowSetTimeout = window.setTimeout;
describe('test a method that uses setTimeout', function(){
    var testObject;
    beforeEach(function () {
        // force setTimeout to be called right away, no matter what time they specify
        jasmine.getGlobal().setTimeout = function (funcToCall, millis) {
            funcToCall();
        };
        testObject = new test();
    });
    afterEach(function() {
        jasmine.getGlobal().setTimeout = realWindowSetTimeout;
    });
    it('should call the method right away', function(){
       testObject.testWithTimeout();
       expect(testObject.timeoutWasCalled).toBeTruthy();
    });
});

I got a good pointer from Andreas in this StackOverflow question.

This would also work for window.setInterval.

Other possible approaches:

  • Create a wrapper module of setTimeout and setInterval methods that can be mocked. This can be mocked with RequireJS or passed into the constructor.
  • Pass the window.setTimeout function into the method (this could get messy).