question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

feature: jest.isolateModules accept an async function for dynamic import()s

See original GitHub issue

🚀 Feature Proposal

Have the ability to pass jest.isolatedModules an async function, and have it wait for the promise to resolve before cleaning up the isolated module registry.

I think this feature might be kind of tricky, because currently it appears there is at most one isolated module registry in a given runtime, meaning that successive calls to jest.isolatedModules with async functions (without waiting for each to resolve) would overlap and fail.

Motivation

Right now, jest.isolateModules() appears to work for static imports only: https://github.com/facebook/jest/blob/v26.4.0/packages/jest-runtime/src/index.ts#L748. But if you use babel-jest and your modules make use of dynamic import()s, the finally block will clean up the isolated modules registry prior to import()s resolving.

My specific use-case for this feature is in defining a helper function for integration tests, that sets up my entire application—mocking some key dependencies—and returns a reference to the root page component mounted in the jsdom environment. This entrypoint uses multiple dynamic imports during its initialization. I’d like the helper function to be self-contained, as I can’t make assumptions about how it’s called. It could be called multiple times within a test suite, for example, hence the desire to use isolatedModules.

Example

  async function loadApp() {
    document.body.innerHTML = '<div id="#app"></div>' // The mount point required by the entrypoint.
    let component

    await jest.isolatedModules(async () => {  // If passed an async function, `isolatedModules` should likewise return a promise.
      jest.doMock('depA', ... )
      ...

      component = await require('path/to/app/entrypoint') // The entrypoint exports a promise resolving to the root component instance, once all initialization is complete.
    })

    return component
  }
  test('App mounts to #app', async () => {
    const vm = await loadApp()
    const mountpoint = document.querySelector('#app')

    expect(vm.el).toBe(mountpoint)
  })

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:26
  • Comments:5

github_iconTop GitHub Comments

15reactions
dreykscommented, May 11, 2021

is this something that is still looked into? having async support for isolateModules would be great. Each of my projects has the following patch so that I can use it with import()s

The change is pretty straightforward, do you think we can incorporate this into the codebase? I can make a proper PR with test coverage and stuff

diff --git a/node_modules/jest-runtime/build/index.js b/node_modules/jest-runtime/build/index.js
index 38c6753..a901ea8 100644
--- a/node_modules/jest-runtime/build/index.js
+++ b/node_modules/jest-runtime/build/index.js
@@ -924,7 +924,7 @@ class Runtime {
     }
   }
 
-  isolateModules(fn) {
+  async isolateModules(fn) {
     if (this._isolatedModuleRegistry || this._isolatedMockRegistry) {
       throw new Error(
         'isolateModules cannot be nested inside another isolateModules.'
@@ -935,7 +935,7 @@ class Runtime {
     this._isolatedMockRegistry = new Map();
 
     try {
-      fn();
+      await fn();
     } finally {
       var _this$_isolatedModule, _this$_isolatedMockRe;
 
@@ -1741,8 +1741,8 @@ class Runtime {
       return jestObject;
     };
 
-    const isolateModules = fn => {
-      this.isolateModules(fn);
+    const isolateModules = async fn => {
+      await this.isolateModules(fn);
       return jestObject;
     };

this of course forces you to await isolateModules in your code if you want to access the jestObject but I think it’s ok. if it’s not ok, however, we can make two different top-level functions isolateModules and isolateModulesAsync that will delegate to the same internal isolaleModules implementation

1reaction
SimenBcommented, Sep 16, 2020

Yeah, this (or something similar) is needed for proper ESM support

Read more comments on GitHub >

github_iconTop Results From Across the Web

The Jest Object
The jest object is automatically in scope within every test file. The methods in the ... This functionality also applies to async functions....
Read more >
Using async / await with dynamic import() for ES6 modules
I am experimenting with the best way to standardise my dynamic import() expressions when importing javascript modules. import() returns a ...
Read more >
Jest Object (API Reference) - w3resource
s overall behavior. Mock Modules. jest.disableAutomock(). This will disable mocking in the module loader. Once this method is called, all ...
Read more >
jest spyon named export - Tecknowledgebase.com
Fortunately, jest has functionality that solves the problem with the jest.spyOn(). With snapshot testing you can take a picture of a React component...
Read more >
jest-repl: Versions | Openbase
29.0.3. 1 month ago. Features. [@jest/environment, jest-runtime] Allow passing a generic type argument to jest.createMockFromModule<T>() method (#13202) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found