Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing a mocked ESM module dynamically will throw an error in node 16.17.0 #498

Closed
3 tasks done
adamraine opened this issue Aug 30, 2022 · 3 comments
Closed
3 tasks done

Comments

@adamraine
Copy link

Description

Importing a mocked ESM module dynamically will throw an error in node 16.17.0 but not 16.16.0.

Issue

Mocking an esm module will result on an error

Environment

  • node -v output: v16.17.0
  • yarn --version output: 1.22.19
  • yarn list testdouble version: testdouble@3.16.5

Code-fenced Examples

❯❯❯ node --loader=testdouble script.js
(node:83826) ExperimentalWarning: Custom ESM Loaders is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:83826) DeprecationWarning: Obsolete loader hook(s) supplied and will be ignored: getFormat, getSource
node:internal/errors:477
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_LOADER_CHAIN_INCOMPLETE]: "testdouble 'load'" did not call the next hook in its chain and did not explicitly signal a short circuit. If this is intentional, include `shortCircuit: true` in the hook's return.
    at new NodeError (node:internal/errors:387:5)
    at ESMLoader.load (node:internal/modules/esm/loader:616:13)
    at async ESMLoader.moduleProvider (node:internal/modules/esm/loader:464:11)
    at async link (node:internal/modules/esm/module_job:67:21) {
  code: 'ERR_LOADER_CHAIN_INCOMPLETE'
}
import * as td from 'testdouble';
await td.replaceEsm('fs', {});
await import('fs');
@searls
Copy link
Member

searls commented Aug 31, 2022

I haven't used td.replaceEsm in earnest, but it would be unusual to import a mocked module from the same code listing.

I would have expected:

import * as td from 'testdouble';
const fs = await td.replaceEsm('fs', {});

And then the subject under test would be loaded and it would in turn import the mocked module. As per this example in the docs.

As a result I'm not sure this is supported. Can you elaborate if it seems like I'm off-base?

@adamraine
Copy link
Author

I haven't used td.replaceEsm in earnest, but it would be unusual to import a mocked module from the same code listing.

Perhaps the minimum repro is too minimum in this case. The same thing happens if the dynamic import occurs further down the dependency tree:

import * as td from 'testdouble';
await td.replaceEsm('fs', {});
await import('./test-module.js');

test-module.js:

await import('fs');

In this situation it doesn't make sense to use the return value of td.replaceEsm because the mocked module needs to be injected into test-module.js.

@connorjclark
Copy link

connorjclark commented Sep 7, 2022

The bug actually came from usage of my fork, not qubbile mainline. Sorry about that. This was fixed by testdouble/quibble#74 – simply rebasing the latest code fixed it for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants