Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use jasmine to test an async function that takes a long time to respond?

I'm using a function to fetch data from webapi. Basicly using $.ajax.

I'm now testing it with waits() like this:

describe('xxxxxxxxxxxxxxxxxxxxx', function () {
  var r;
  it('fetchFilter', function () {
    runs(function () {
      model.fetch(opts)
      .done(function(data) {
        r = data;
      });
    });

    waits(2000);

    runs(function () {
      expect(r[0].gender).toBeDefined();
    });
  });
});

The problem is:

  1. It's not guaranteed that waits(2000) will do the job well. Due to various reasons(network connections, algorithm efficiency of the api it self, etc.), I may have to waits(5000) or more, or for some models waits(500) is enough. And the most annoying thing is that it's all out of control.
  2. A lot of waits() makes the test-specs-runs waste a lot of time waiting. The time of running the whole suite is too long to accept.

Is there some best practice of doing there kind of things?

PS: I know that unit test should not be applied to some function that relies on webapi or database. But I'm working with a single-page-js-heavy-webapp. The data fetching process is as important as how I will consume them with js models.

like image 514
hbrls Avatar asked Jan 14 '13 09:01

hbrls


People also ask

How do you test async in Jasmine?

You can check on the spied on function in . then of the async call. This is where you can use toHaveBeenCalled or toHaveBeenCalledWith to see if it was called. You should also check if the result of the promise is the expected output you want to see via the toEqual matcher.

How do I use async await in Jasmine?

async / awaitasync functions implicitly return a promise. Jasmine will wait until the returned promise is either resolved or rejected before moving on to the next thing in the queue. Rejected promises will cause a spec failure, or a suite-level failure in the case of beforeAll or afterAll .

Does Jasmine support asynchronous operation?

Jasmine has a built-in way to handle async code and that's by the passed in done function in the test specs.

How do you increase Jasmine timeout?

To change the timeout on a Jasmine Node async spec, we can set the jasmine. DEFAULT_TIMEOUT_INTERVAL value. describe("long asynchronous specs", () => { let originalTimeout; beforeEach(() => { originalTimeout = jasmine.


1 Answers

waitsFor() will wait for a specified latch callback to return true (it will try many time every few ms). It will also raise an exception if the specified timeout (5000ms in this case) is exceeded.

describe('xxxxxxxxxxxxxxxxxxxxx', function () {
  var r, fetchDone;

  it('fetchFilter', function () {

    runs(function () {
      model.fetch(opts).done(function(data) {
        r = data;
        fetchDone = true;
      });
    });

    waitsFor(function() { 
      return fetchDone; 
    }, 5000); 

    runs(function () {
      expect(r[0].gender).toBeDefined();
    });

  });
});

Check the Jasmine docs for more info on waitsFor() and runs()

like image 85
istepaniuk Avatar answered Nov 15 '22 14:11

istepaniuk