Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jasmine.js expect() does not work inside an asynchronous callback

I'm getting acquainted with Jasmine (http://pivotal.github.com/jasmine/) and found something rather baffling:

it("should be able to send a Ghost Request", function() {
  var api = fm.api_wrapper;

  api.sendGhostRequest(function(response) {
    console.dir('server says: ', response);
  });

  expect(true).toEqual(false);
});

Fails as expected.

However, moving the expect call inside the callback:

it("should be able to send a Ghost Request", function() {
  var api = fm.api_wrapper;

  api.sendGhostRequest(function(response) {
    console.dir('server says: ', response);
    expect(true).toEqual(false);
  });
});

Somehow passes :O

After some debugging: api.sendGhostRequest() does an asynchronous ajax request, and jasmine rushes past before the request has completed.

Hence the question:

How do I get jasmine to wait for ajax execution before ascertaining the test result?

like image 997
Val Redchenko Avatar asked Feb 28 '13 17:02

Val Redchenko


People also ask

Does Jasmine support asynchronous operation?

Jasmine supports three ways of managing asynchronous work: async / await , promises, and callbacks.

What is done () in Jasmine?

Using the done() Method in Your Jasmine-driven Asynchronous JavaScript Tests. Jasmine. Async is an add-on library for Jasmine that provides additional functionality to do asynchronous testing. Modeled after Mocha's async test support, it brings the done() function to the Jasmine unit testing environment.

What is done function?

done is just a non-official standard name for a function (a.k.a callback) that informs the calling function (parent in stacktrace) that a task is completed.


1 Answers

Edit for Jasmine 2

Asynchronous tests have become much simpler in Jasmine 2. Any test that needs to handle asynchronous code can be written with a callback which will indicate the completion of the test. See the Jasmine 2 docs under the header Asynchronous Support

it('should be able to send a ghost request', (done) => {
    api.sendGhostRequest((response) => {
        console.log(`Server says ${response}`);
        expect(true).toEqual(false);
        done();
    });
});

Jasmine 1

Have a look at waitsFor() and runs() on the Jasmine site under the header Asynchronous Support.

Use of runs and waitsfor should force Jasmine to wait for the ajax call to finish or for some timeout.

The code would look like:

it("should be able to send a Ghost Request", function() {
    runs(function() {
        api.sendGhostRequest(function(response) {
            console.dir('server says: ', response);
            flag = true;
        });
    }, 500);

    waitsFor(function() {
        return flag;
    }, "Flag should be set", 750);

    runs(function() {
        expect(true).toEqual(false);
    });
}

In which case the expect would fail.

like image 106
halfs13 Avatar answered Nov 07 '22 08:11

halfs13