question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature: clear all Timers when doing restore

See original GitHub issue

We understand you have a problem and are in a hurry, but please provide us with some info to make it much more likely for your issue to be understood, worked on and resolved quickly.

  • FakeTimers version : please verify that the bug exists in the latest FakeTimers release 9.0.11
  • Environment : node 16.14.2
  • Example URL :
  • Other libraries you are using: mocha for showing the behavior.

What did you expect to happen?

When I start to useFakeTimers, all global Timer functions in Node will be replaced by Sinon, including the clear methods. It means if the Timers are set up after fakeTimer is activated, and Sinon is restored before all pending Timers are cleared, it will be not possible to clear the timers afterward.

I’d expect there’s an API to opt-in clearing all pending Timers that are set after fakeTimer is activated on doing sandbox.restore(), it will bring more predictivity to the test behavior, especially when those Timers are set by the libs where the TimerIDs are not trackable.

To add to it, this issue can happen a lot when testing codes that work with RxJS, which heavily relies on clearInterval to work well to clean up the ongoing tasks, otherwise an explicit error will be thrown in NodeJS process (see RxJS code)

What actually happens

as described above.

How to reproduce

Describe with code how to reproduce the faulty behaviour or link to code on JSBin or similar

Really long code sample or stacktrace

// I’m using mocha here

it('fakeTimer', async function () {
    const clock = sandbox.useFakeTimers();
    const spy = sandbox.spy();

    const intervalId = setInterval(spy, 100);

    console.log('about to tick 1s');
    await clock.tickAsync(1000);
    sandbox.assert.callCount(spy, 10);

    console.log('about to tick 1s');
    await clock.tickAsync(1000);
    sandbox.assert.callCount(spy, 20);

    sandbox.resetHistory();

    sandbox.restore();
    clearInterval(intervalId); // this will simply not work, because clearInterval is different from the one Sinon is using, and it's not possible clear the Timers Sinon has set. In this example we can move this line before sandbox.restore(); to solve, but if we can't get the intervalId then we can't clear it.

    console.log('about to tick 1s (after clearInterval)');
    await clock.tickAsync(1000);
    sandbox.assert.callCount(spy, 0);
});

// I had this as a workaround

it('fakeTimer', async function () {
    const clock = sandbox.useFakeTimers();
    const spy = sandbox.spy();
    const setIntervalSpy = sandbox.spy(global, 'setInterval');

    const intervalId = setInterval(spy, 100);

    console.log('about to tick 1s');
    await clock.tickAsync(1000);
    sandbox.assert.callCount(spy, 10);

    console.log('about to tick 1s');
    await clock.tickAsync(1000);
    sandbox.assert.callCount(spy, 20);

    setIntervalSpy.returnValues.map((intervalTimerId) => global.clearInterval(intervalTimerId));

    sandbox.resetHistory(); // this has to be before restore...
    sandbox.restore();

    console.log('about to tick 1s (after clearInterval)');
    await clock.tickAsync(1000);
    sandbox.assert.callCount(spy, 0);
});

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
fatso83commented, May 24, 2022

Yes, that should be right.

I wrote some small tests to make it a bit more clear

Very smart, I took the tip of Sinon’s original author Christian Johansen in his TDD book on JS and created a repo for learning tests years ago. Very nice for solidifying understanding.

1reaction
sasaxingcommented, May 24, 2022

https://runkit.com/xiaosha/628d2d19e3e2060008656cd5 I try to make 2 tests, one with original sinon, the second clearable sinon. Both do the same steps, and assert same expectation, while the first will fail but second pass. The only difference is ClearableSinon does some more thing during restore.

Read more comments on GitHub >

github_iconTop Results From Across the Web

javascript: Clear all timeouts? - Stack Overflow
Basically, setTimeout/setInterval ID's go in consecutive order, so just create a dummy timeout function to get the highest ID, then clear interval on...
Read more >
Return iPhone settings to their defaults - Apple Support
Return iPhone settings to their defaults · Go to Settings > General > Transfer or Reset iPhone > Reset. · Choose an option:...
Read more >
TIA Portal: Resetting and Presetting Timers (TON ... - YouTube
How to Reset and Preset Timers while they are running?...what does it all mean and why do you need it?Find it out here!If...
Read more >
Timer reset or cancel in JavaScript function clearTimeout:
We can reset or clear the timer before the time out of the timer by using the function clearTimeout(). Here is the general...
Read more >
Timer Mocks - Jest
Timers can be restored to their normal behavior with jest. ... be useful in some tests to be able to clear all of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found