4

I have a working ractive component test case already with mocha using sinon ans able to mock an ajax call but with the help of setTimeout(function(){}, 100) and I dont like using it.

beforeEach(function () {
  this.container = document.createElement('div');
  document.body.appendChild(this.container);

  this.server = sinon.fakeServer.create();
  this.server.respondWith(
    "GET",
    "/api/url",
    [
      200,
      { "Content-Type": "application/json" },
      '{"data": []}'
    ]
  );
});

afterEach(function () {
  document.body.removeChild(this.container);
});

it("should fetch data from server", function (done) {
  var server = this.server;
  var Component = require('rvc!path/to/component');
  var component = new Component({
    el: this.container,
  });

  setTimeout( function() {
    server.respond();

    expect(component.findAll('.list li').length).to.equal(7);
    done();
  }, 100);

});

As you can see in the code above, I'm using the setTimeout to make sure that the ajax call (mock) was made before having the actual test of the component.

Is there a way that I can eliminate the setTimeout having the same effect? Thanks!

cprakashagr
  • 751
  • 11
  • 28

1 Answers1

3

Assuming that your http request is happening in the component, then it won't get the data until the next tick of the event loop.

One approach is to use setTimeout as you have done, but you probably can lower the timeout (use autoRespondAfter to adjust the sinon response delay).

If your component code supports it, an approach that seems well suited to your use case from the sinon fakeServer docs would be to use the respondImmediately option:

If set, the server will respond to every request immediately and synchronously. This is ideal for faking the server from within a test without having to call server.respond() after each request made in that test. As this is synchronous and immediate, this is not suitable for simulating actual network latency in tests or mockups.

this.server = sinon.fakeServer.create({ respondImmediately: true })

// now no need to call server.respond() and calls are returned synchronously!
martypdx
  • 3,702
  • 14
  • 22
  • Thanks for the output. :) – jaygel adoptante Mar 16 '16 at 05:56
  • What do you mean by 'if your component codes supports it'? I tried respondImmediately but still I need to add the setTimeout. respondImmediately seems working since I dont need the server.respond() for the server to respond. – jaygel adoptante Mar 17 '16 at 06:21
  • I mean that changing an API that is expected to be async to sync may have intended consequences if the code wasn't written with that in mind. – martypdx Mar 18 '16 at 15:38