Skip to content

Commit 5137ffa

Browse files
committed
fix: mock modules must not use cache:true on Node >=24.17
The 24.17/24.18 module-loader changes broke cache:true mock modules: the mocked specifier exposes its export names with values never bound, so ESM sources importing { Redis } from the mocked ioredis received undefined (TypeError: Redis is not a constructor) — reproduced 1:1 in docker node:24 (24.18.0) while node 24.16 still worked. cache:false restores correct binding on every supported version (verified on 22.23.1, 24.16.0 and 24.18.0 — 249/249 each). Instance caching was not load-bearing for these mocks: all shared state lives on the exported references themselves (RedisClientMock statics), so each re-evaluation serves the same objects.
1 parent 31d7dcf commit 5137ffa

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

test/mocks/mockBuiltin.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@ import { mock, type MockModuleOptions } from 'node:test';
3535
* which requires the default export to be a plain object (a bare class as
3636
* the default with named exports alongside is rejected by the runtime).
3737
*
38-
* `cache: true` keeps mock-require's semantics: every `require()` of the
39-
* mocked specifier returns the same module instance, so a test may patch a
40-
* property in place and the code under test observes the change.
38+
* `cache: false` is required: as of the Node 24.17/24.18 module-loader
39+
* changes, `cache: true` mock modules expose their export names with the
40+
* values never bound (importing `{ Redis }` yields undefined). Instance
41+
* caching is not load-bearing for these mocks anyway — every piece of
42+
* shared state lives on the exported references themselves (for example
43+
* RedisClientMock statics), so each re-evaluation serves the same objects.
4144
*
4245
* @param {Record<string, unknown>} exports - mock exports, `default` key being
4346
* the default export
@@ -47,7 +50,7 @@ export function moduleMockOptions(
4750
exports: Record<string, unknown>,
4851
): MockModuleOptions {
4952
const { default: defaultExport, ...namedExports } = exports;
50-
const options: MockModuleOptions = { cache: true };
53+
const options: MockModuleOptions = { cache: false };
5154

5255
if (defaultExport !== undefined) {
5356
options.defaultExport = defaultExport;

0 commit comments

Comments
 (0)