Jasmine how to use done()?

12,067

Solution 1

You need to move your function that handles the response into the it body. Things get reorganized a bit:

// *** Pass "done" in the function, Jasmine automagically knows what to do with it
it ('should be able to invoke a web service with POST as the HTTP method', function(done) {
    // *** Local callback to use here
    let localCallback = function(/* arguments */) {
        // *** Local copy of response
        let response = null;
        // *** Copy your stuff into response
        ...
        // *** Moved your tests here
        // Can now resume tests
        expect(response.post.name).toEqual('StackOverflow');     
        // *** Let Jasmine know this "it" is finished  
        done();
    }
    // *** Do your setup here to use the local callback above
    let request = ...(localCallback);
    // Data
    let data = {name: 'StackOverflow'};
    // POST
    let params = {method: 'POST'};
    // This call is asynchronous
    // The URL just echoes back the get and post parameters
    request.send(url, data, params);
});

Solution 2

If your request is promise based you would do something like this:

it ('should be able to invoke a web service with POST as the HTTP method',
  function(done) {
    // Data
    let data = {name: 'StackOverflow'};
    // POST
    let params = {method: 'POST'};
    // This call is asynchronous
    // The URL just echoes back the get and post parameters
    request.send(url, data, params).then(
      funciton(response) {
        expect(response.post.name).toEqual('StackOverflow');
        done();
      }
    ).catch(
      function(err) {
        done(new Error(err));
      }
    );
  }
);

This will only run the expect when the data is returned.

done is called with no params to indicate that your code is finished.

done is called with an Error object to indicate that something failed. The message of the Error object should tell what failed.

Share:
12,067
Yimin Rong
Author by

Yimin Rong

I like eating and manual labor.

Updated on June 28, 2022

Comments

  • Yimin Rong
    Yimin Rong about 2 years

    I'm trying to wrap my head around done() so I can test an asynchronous web service call. The documentation from Jasmine and others don't make sense to me, I can't see where the code goes, where the test for completion goes, or where the actual Jasmine tests go. They don't even use any asynchronous calls.

    This question previously asked about runs() and waitsFor(), they've been deprecated in 2.0, apparently because "It's much simpler." using done()! In any case, on my version 2.6, using done() anywhere in the code brings up a reference error that it isn't defined, so I'm really not sure what's going on.

    This is the code I'd like to be able to adapt. The code to call is helper.send(url, data, params); and the code is done when response !== null.

    it ('should be able to invoke a web service with POST as the HTTP method', function() {
        // Data
        let data = {name: 'StackOverflow'};
        // POST
        let params = {method: 'POST'};
        // This call is asynchronous
        // The URL just echoes back the get and post parameters
        request.send(url, data, params);
        // Need to wait for response !== null
        // ...
        // Can now resume tests
        expect(response.post.name).toEqual('StackOverflow');
    });
    

    If anyone can help with how to reorganize this to work with done(), it would be much appreciated.

    • Daniel A. White
      Daniel A. White about 6 years
      does your request do a promise or callback?
    • Yimin Rong
      Yimin Rong about 6 years
      With a callback, it copies everything to response.
  • Yimin Rong
    Yimin Rong about 6 years
    Thank you, the comments make it much clearer how it works.
  • kaskelotti
    kaskelotti over 5 years
    +1 for describing how/when done is called with parameters. Even the official documentation seems to lack this. I was quite confused when testing async code using promises and this was always failing tests .then(done) (correct is .then(result => done()))
  • Intervalia
    Intervalia over 5 years
    Yeah. Calling .then(done) will pass the resolved data into done and passing anything into done is telling it that an error has occurred. So calling .then(result => done()) is how to tell done that no error has occurred.
  • Manu Chadha
    Manu Chadha over 5 years
    Buddy - what happens if I don't use done? Would Jasmine continue to the next spec or mark this one as pass (because there is nothing to expect after request.send) without waiting for the localCallback to run?
  • Donny groezinger
    Donny groezinger over 2 years
    what if done() isn't recognized in my test cases? I can't seem to find any documentation on it.