Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout not triggered while using Sinon's fake timers

I have a test similar to what is shown below. Basically I want to test if a specific method is getting delayed.

The following example works as expected, i.e. the resolve method gets called and the test passes:

it(`should delay execution by 1 second`, function () {
  const clock = sandbox.useFakeTimers();

  const p = new Promise(function (resolve) {
    setTimeout(resolve, 1000);
  });

  clock.tick(1000);

  return p;
});

However, if I wrap the setTimeout in another Promise, the resolve never gets called:

it(`should delay execution by 1 second`, function () {
  const clock = sandbox.useFakeTimers();

  const p = Promise.resolve()
    .then(() => {
      return new Promise(function (resolve) {
        setTimeout(resolve, 1000); // resolve never gets called
      });
    });

    clock.tick(1000);

    return p;
  });

What's the problem here?

I'm using Sinon 2.1.0 and native promises on Node 6.9.5.

like image 924
Hugo Durães Avatar asked Oct 26 '25 17:10

Hugo Durães


1 Answers

The problem appears to be that you are ticking the clock before the timeout is started - which happens asynchronously, in a promise callback, in your second snippet.

This should work:

it(`should delay execution by 1 second`, function () {
  const clock = sandbox.useFakeTimers();

  return Promise.resolve().then(() => {
    return new Promise(function (resolve) {
      setTimeout(resolve, 1000);
      clock.tick(1000); // resolve gets called now
    });
  });
});
like image 135
Bergi Avatar answered Oct 29 '25 07:10

Bergi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!