Skip to content
21 changes: 16 additions & 5 deletions lib/test/mock_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ const { normalizeReferrerURL } = require('internal/modules/helpers');
let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => {
debug = fn;
});
const { createRequire, isBuiltin } = require('module');
const { createRequire, isBuiltin, _resolveFilename } = require('module');
const { defaultGetFormatWithoutErrors } = require('internal/modules/esm/get_format');
const { defaultResolve } = require('internal/modules/esm/resolve');

// TODO(cjihrig): This file should not be exposed publicly, but register() does
// not handle internal loaders. Before marking this API as stable, one of the
Expand Down Expand Up @@ -95,11 +97,20 @@ async function resolve(specifier, context, nextResolve) {
if (isBuiltin(specifier)) {
mockSpecifier = ensureNodeScheme(specifier);
} else {
// TODO(cjihrig): This try...catch should be replaced by defaultResolve(),
// but there are some edge cases that caused the tests to fail on Windows.
let format;

if(context.parentURL) {
format = defaultGetFormatWithoutErrors(pathToFileURL(context.parentURL));
}

try {
const req = createRequire(context.parentURL);
specifier = pathToFileURL(req.resolve(specifier)).href;
if (format === 'module') {
specifier = defaultResolve(specifier, context).url;
} else {
specifier = pathToFileURL(
createRequire(context.parentURL).resolve(specifier)
).href;
}
} catch {
const parentURL = normalizeReferrerURL(context.parentURL);
const parsedURL = URL.parse(specifier, parentURL)?.href;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export let string = 'original esm string';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { mock } from 'node:test';

try {
if (mock.module) mock.module('Whatever, this is not significant', { namedExports: {} });
} catch {}

const { string } = await import('./basic-esm-without-extension');
console.log(`Found string: ${string}`); // prints 'original esm string'
15 changes: 15 additions & 0 deletions test/parallel/test-runner-mocking.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
const common = require('../common');
const assert = require('node:assert');
const { mock, test } = require('node:test');
const fixtures = require('../common/fixtures');
test('spies on a function', (t) => {
const sum = t.mock.fn((arg1, arg2) => {
return arg1 + arg2;
Expand Down Expand Up @@ -1054,3 +1055,17 @@ test('setter() fails if getter options is true', (t) => {
t.mock.setter({}, 'method', { getter: true });
}, /The property 'options\.setter' cannot be used with 'options\.getter'/);
});

test('wrong import syntax should throw error after module mocking.', async () => {
const { stdout, stderr } = await common.spawnPromisified(
process.execPath,
[
'--experimental-test-module-mocks',
'--experimental-default-type=module',
fixtures.path('module-mocking/wrong-import-after-module-mocking.js'),
]
);

assert.equal(stdout.toString(), '')
assert.match(stderr.toString(), /Error \[ERR_MODULE_NOT_FOUND\]: Cannot find module/)
});