fake-timers: NodeJS "timers" module is not mocked
- FakeTimers version : v10.1.0
- Environment : Node.js v18.12.1
- Other libraries you are using: jest v29.5.0
What did you expect to happen?
NodeJS’s timers module to be mocked upon FakeTimers.install().
What actually happens It’s not mocked.
How to reproduce
let timers = require("timers");
let FakeTimers = require("@sinonjs/fake-timers");
let clock;
beforeEach(() => {
clock = FakeTimers.install();
});
it("doesn't work", () => {
let timerDone = false;
timers.setTimeout(()=>{timerDone=true;}, 1000);
clock.tick(1001);
expect(timerDone).toBe(true);
});
afterEach(() => {
clock.uninstall();
});
I was testing some code that is working with socket.io and was wondering why my sockets kept closing with ping time outs. Turns out engine.io is using timers.* instead of the corresponding global functions.
TBH I’m not quite sure if a fix belongs into this library or into jest’s useFakeTimers function. However, the README here says it’d mock all “native” timers when FakeTimers.install is called without arguments, so it should maybe also include NodeJS’s core module timers.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 17 (17 by maintainers)
Sniffing out
requireshould work fine in Jest as that should work the same as Node, but that won’t work forimportdeclarations or expressions. I think that would need to hook into the module mocking directly. I haven’t looked into it, thothe referenced issue is # #469 btw
Thanks guys 🙏
As it turns out, this doesn’t solve my initial problem, though. Jest is using a custom global object but I made it so that the timers module isn’t touched unless the patched object is the “default” global object. So upon
jest.useFakeTimersthe timers module stays the same.Despite that, I still think it’s not a good idea to have fake-timers change the timers module for every call to “install” as this might lead to unexpected behavior if multiple objects are being patched and reverted.
Ah, good catch. I’ll create a new one, referencing this.
A loader (not fun) or using top level await with dynamic import (easy and also works)