Skip to content

Commit 99e4685

Browse files
JakobJingleheimerRafaelGSS
authored andcommitted
test_runner: support mocking json modules
PR-URL: #58007 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 77d11f9 commit 99e4685

5 files changed

Lines changed: 57 additions & 9 deletions

File tree

‎doc/api/test.md‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,6 +2168,11 @@ test('spies on an object method', (t) => {
21682168
added:
21692169
- v22.3.0
21702170
- v20.18.0
2171+
changes:
2172+
- version:
2173+
- REPLACEME
2174+
pr-url: https://github.com/nodejs/node/pull/58007
2175+
description: Support JSON modules.
21712176
-->
21722177

21732178
> Stability: 1.0 - Early development
@@ -2191,10 +2196,10 @@ added:
21912196
mock will throw an exception when used as a CJS or builtin module.
21922197
* Returns: {MockModuleContext} An object that can be used to manipulate the mock.
21932198

2194-
This function is used to mock the exports of ECMAScript modules, CommonJS
2195-
modules, and Node.js builtin modules. Any references to the original module
2196-
prior to mocking are not impacted. In order to enable module mocking, Node.js must
2197-
be started with the [`--experimental-test-module-mocks`][] command-line flag.
2199+
This function is used to mock the exports of ECMAScript modules, CommonJS modules, JSON modules, and
2200+
Node.js builtin modules. Any references to the original module prior to mocking are not impacted. In
2201+
order to enable module mocking, Node.js must be started with the
2202+
[`--experimental-test-module-mocks`][] command-line flag.
21982203

21992204
The following example demonstrates how a mock is created for a module.
22002205

‎lib/internal/test_runner/mock/loader.js‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,17 @@ async function load(url, context, nextLoad) {
118118
// Treat builtins as commonjs because customization hooks do not allow a
119119
// core module to be replaced.
120120
// Also collapse 'commonjs-sync' and 'require-commonjs' to 'commonjs'.
121-
constformat=(
122-
original.format==='builtin'||
123-
original.format==='commonjs-sync'||
124-
original.format==='require-commonjs') ? 'commonjs' : original.format;
121+
letformat=original.format;
122+
switch(original.format){
123+
case'builtin': // Deliberate fallthrough
124+
case'commonjs-sync': // Deliberate fallthrough
125+
case'require-commonjs':
126+
format='commonjs';
127+
break;
128+
case'json':
129+
format='module';
130+
break;
131+
}
125132

126133
constresult={
127134
__proto__: null,

‎lib/internal/test_runner/mock/mock.js‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,14 @@ const kMockUnknownMessage = 3;
7070
constkWaitTimeout=5_000;
7171
constkBadExportsMessage='Cannot create mock because named exports '+
7272
'cannot be applied to the provided default export.';
73-
constkSupportedFormats=['builtin','commonjs','module','module-typescript','commonjs-typescript'];
73+
constkSupportedFormats=[
74+
'builtin',
75+
'commonjs-typescript',
76+
'commonjs',
77+
'json',
78+
'module-typescript',
79+
'module',
80+
];
7481
letsharedModuleState;
7582

7683
classMockFunctionContext{
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"foo":"bar"}

‎test/parallel/test-runner-module-mocking.js‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,34 @@ test('ESM mocking with namedExports option', async (t) => {
365365
});
366366
});
367367

368+
test('JSON mocking',async(t)=>{
369+
awaitt.test('with defaultExport',async(t)=>{
370+
constfixturePath=fixtures.path('module-mocking','basic.json');
371+
constfixture=pathToFileURL(fixturePath);
372+
const{default: original}=awaitimport(fixture,{with: {type: 'json'}});
373+
374+
assert.deepStrictEqual(original,{foo: 'bar'});
375+
376+
constdefaultExport={qux: 'zed'};
377+
378+
t.mock.module(fixture,{ defaultExport });
379+
380+
const{default: mocked}=awaitimport(fixture,{with: {type: 'json'}});
381+
382+
assert.deepStrictEqual(mocked,defaultExport);
383+
});
384+
385+
awaitt.test('throws without appropriate import attributes',async(t)=>{
386+
constfixturePath=fixtures.path('module-mocking','basic.json');
387+
constfixture=pathToFileURL(fixturePath);
388+
389+
constdefaultExport={qux: 'zed'};
390+
t.mock.module(fixture,{ defaultExport });
391+
392+
awaitassert.rejects(()=>import(fixture),/importattribute/);
393+
});
394+
});
395+
368396
test('modules cannot be mocked multiple times at once',async(t)=>{
369397
awaitt.test('CJS',async(t)=>{
370398
constfixture=fixtures.path('module-mocking','basic-cjs.js');

0 commit comments

Comments
 (0)