node icon indicating copy to clipboard operation
node copied to clipboard

MockTimers does not mock Timer properties

Open mscottnelson opened this issue 1 year ago • 0 comments

Version

v20.11.0

Platform

Darwin Kernel Version 23.2.0

Subsystem

node:test

What steps will reproduce the bug?

When performing tests that require the mocking of timers, it is extremely helpful to have all the aspects of timers mocked. Today, MockTimers does not match the API of Timers. This can cause tests to fail simply because the MockTimer will error with normal usage. When testing something that is making heavy usage of timing, this makes the MockTimer API unsuitable for testing timing-related code.

For example:

import { mock } from 'node:test';

const t1 = setInterval(()=>{},100); // returns Timer
t1.unref(); // returns Timer
mock.timers.enable();
const t2 = setInterval(()=>{},100); // returns Object: null prototype
t2.unref(); // Uncaught TypeError

Perhaps the tooling that currently overrides timer behavior could instead be a forwarding Proxy or similar?

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

Timers returned by the MockTimer API should match the API of the Timers API.

Expected:

require("node:test").mock.timers.enable();
setInterval(()=>{}).unref();
/**
> Timeout {
  _idleTimeout: 1,
  _idlePrev: [TimersList],
  _idleNext: [TimersList],
  _idleStart: 34,
  _onTimeout: [Function (anonymous)],
  _timerArgs: undefined,
  _repeat: 1,
  _destroyed: false,
  [Symbol(refed)]: false,
  [Symbol(kHasPrimitive)]: false,
  [Symbol(asyncId)]: 2,
  [Symbol(triggerId)]: 1
}
**/

What do you see instead?

Actual:

require("node:test").mock.timers.enable();
setInterval(()=>{}).unref()

TypeError: setInterval(...).unref is not a function

Additional information

No response

mscottnelson avatar Feb 08 '24 02:02 mscottnelson