0
votes

I am using jasmine 2.0.

I am trying to understand the done() function.

With the following basic jasmine code:

describe('Jasmine 2.0 done()', function() {

    beforeEach(function () {
        console.log('install');
        jasmine.clock().install();
    });

    afterEach(function () {
        console.log('uninstall');
        jasmine.clock().uninstall();
    });


    it('should wait 1ms then complete', function (done) {

        setTimeout(function(){
            console.log('async');
            expect(true).toBe(true);
            done();      
        }, 1)

    });

});

What I think I see happen:

  • beforeEach runs, installing the clock, logs "install"
  • The test runs, the setTimeout does not do anything
  • The test waits for 5 seconds (the default timeout jasmine has before failing)
  • The test fails because done() is never called.
  • I know this because I get the error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
  • afterEach then runs anyway, uninstalls the clock and logs "uninstall"

I would expect that

  • beforeEach runs, installing the clock and logs "install"
  • The test runs, waits for one millisecond, runs the log, the expect and done()
  • afterEach runs, uninstalls the clock and logs "uninstall"
  • The test passes with no error

I think this because the documentation says

And this spec will not complete until its done is called.

So I assumed afterEach would wait until done() is called to execute.

I have tried adding done() in the afterEach too

afterEach(function (done) {
    console.log('uninstall');
    jasmine.clock().uninstall();
    done();
});

This made no difference.

Why does this test not succeed?

What am I not understanding about the done() function?

plunker to show the problem

2

2 Answers

1
votes

When jasmine's mock clock is installed setTimeout behavior is overridden. Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds (link to jasmine docs)

Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds.

In your case test spec would look like this:

describe('Jasmine 2.0 done()', function() {

    beforeEach(function () {
        console.log('install');
        jasmine.clock().install();
    });

    afterEach(function () {
        console.log('uninstall');
        jasmine.clock().uninstall();
    });


    it('should wait 1ms then complete', function (done) {

        setTimeout(function(){
            console.log('async');
            expect(true).toBe(true);
            done();      
        }, 1);

        jasmine.clock().tick(1);
    });

});
0
votes

With Jasmine asynchronous testing, we have to call the async code in the beforeEach() and afterEach() function that runs before each it() function block within a describe() function block.

This means that the done() callback has to be called within the above mentioned methods, else the test will become synchronous and it blocks the calling thread if it exceeds the timeout interval.

beforeEach(function (done) {
    console.log('install');
    jasmine.clock().install();
    done(); 
});

afterEach(function (done) {
    console.log('uninstall');
    jasmine.clock().uninstall();
    done(); 
});

Here is a working JSFiddle.