Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with useFakeTimers: Promise are freeze when resolve it from setTimeout #1397

Closed
qoter opened this issue May 5, 2017 · 11 comments
Closed

Comments

@qoter
Copy link

qoter commented May 5, 2017

  • Sinon version : 2.2.0
  • Environment : Node.js v6.10.2
  • Other libraries: mocha 3.3.0

Code example

it('promise freeze', () => {
    let clock = sinon.useFakeTimers();
    let p = Promise.resolve()
        .then(() => new Promise(resolve => setTimeout(resolve, 5)));
    clock.tick(1000);
    return p;
});

I expect that test will pass.
But test fail with timeout and promise are frozen.
Without sinon.useFakeTimers() this test will pass.

@lucasfcosta
Copy link
Member

lucasfcosta commented May 6, 2017

Hi @qoter, thanks for your issue 😄

I believe this happens because you either gotta use a timer from the clock variable you assigned useFakeTimers to or you need to call the install method.

This is one of the possible fixes for your test:

let clock = fakeTimers.useFakeTimers();
let p = Promise.resolve()
  .then(() => new Promise(resolve => fakeTimers.timers.setTimeout(resolve, 5)));
clock.tick(1000);
return p;

The other one, using install to replace the global setTimeout function can be used by installing the lolex module, as you can see in this section at Lolex docs.

@qoter
Copy link
Author

qoter commented May 7, 2017

Hello @lucasfcosta)))
Your test works!)
But when i use lolex.install() to replace global setTimeout promise still frozen.

Examples:

  1. It works (use lolex.timers.setTimeout)
let clock = lolex.install();
let p = Promise.resolve()
    .then(() => new Promise(resolve => lolex.timers.setTimeout(resolve, 5)));
clock.tick(1000);
return p;
  1. It fails with timeout (replace global setTimeout)
let clock = lolex.install();
let p = Promise.resolve()
    .then(() => new Promise(resolve => setTimeout(resolve, 5)));
clock.tick(1000);
return p;
  1. btw it also works (not return promise from then)
let clock = lolex.install();
let p = new Promise(resolve => setTimeout(resolve, 5));
clock.tick(1000);
return p;

I really do not understand why this happens.
Thank you!

@mroderick
Copy link
Member

Has this stalled?

@qoter
Copy link
Author

qoter commented May 30, 2017

@mroderick
Sorry, i didn't understand you(
What do you mean?

@fatso83
Copy link
Contributor

fatso83 commented May 30, 2017

Are you using any Promise libraries? They often use timers to create polyfills, which might be affected by faking time.

@qoter
Copy link
Author

qoter commented May 30, 2017

@fatso83 No, I use default Promise from node.js

@macdonaldr93
Copy link

+1 I'm having this issue too. Just using native Promise

@stale
Copy link

stale bot commented Jan 13, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jan 13, 2018
@stale stale bot closed this as completed Jan 20, 2018
@robertstettner
Copy link

+1 I'm having this issue too.

@fatso83 fatso83 reopened this Jun 6, 2018
@stale stale bot removed the stale label Jun 6, 2018
@fatso83
Copy link
Contributor

fatso83 commented Jun 6, 2018

We should probably move this to lolex, to get it fixed.

@fatso83
Copy link
Contributor

fatso83 commented Jun 6, 2018

This issue was moved to sinonjs/fake-timers#194

@fatso83 fatso83 closed this as completed Jun 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants