From 0cfc2ad2991373324306c8daf962c41d0f37793c Mon Sep 17 00:00:00 2001 From: Wing Chau Date: Sat, 3 Sep 2022 13:59:27 +0100 Subject: [PATCH] docs: ESM update (#13191) --- .eslintrc.cjs | 1 + docs/ECMAScriptModules.md | 59 ++++++++++++++++++- docs/ManualMocks.md | 6 ++ .../version-25.x/ECMAScriptModules.md | 38 +++++++++++- .../version-25.x/ManualMocks.md | 6 ++ .../version-26.x/ECMAScriptModules.md | 38 +++++++++++- .../version-26.x/ManualMocks.md | 6 ++ .../version-27.x/ECMAScriptModules.md | 59 ++++++++++++++++++- .../version-27.x/ManualMocks.md | 6 ++ .../version-28.x/ECMAScriptModules.md | 59 ++++++++++++++++++- .../version-28.x/ManualMocks.md | 6 ++ .../version-29.0/ECMAScriptModules.md | 59 ++++++++++++++++++- .../version-29.0/ManualMocks.md | 6 ++ .../version-25.x-sidebars.json | 4 ++ 14 files changed, 343 insertions(+), 10 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index c7a6e781bc9b..44dce82fda45 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -182,6 +182,7 @@ module.exports = { { files: ['docs/**/*', 'website/**/*'], rules: { + 'no-redeclare': 'off', 'import/order': 'off', 'import/sort-keys': 'off', 'no-restricted-globals': ['off'], diff --git a/docs/ECMAScriptModules.md b/docs/ECMAScriptModules.md index 199b7ff61b8c..d838c707248f 100644 --- a/docs/ECMAScriptModules.md +++ b/docs/ECMAScriptModules.md @@ -7,7 +7,7 @@ Jest ships with _experimental_ support for ECMAScript Modules (ESM). > Note that due to its experimental nature there are many bugs and missing features in Jest's implementation, both known and unknown. You should check out the [tracking issue](https://github.com/facebook/jest/issues/9430) and the [label](https://github.com/facebook/jest/labels/ES%20Modules) on the issue tracker for the latest status. -> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `14.13.1`). +> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `18.8.0`). With the warnings out of the way, this is how you activate ESM support in your tests. @@ -38,4 +38,59 @@ import.meta.jest.useFakeTimers(); // jest === import.meta.jest => true ``` -Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. +## Module mocking in ESM + +Since ESM evaluates static `import` statements before looking at the code, the hoisting of `jest.mock` calls that happens in CJS won't work for ESM. To mock modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules - the same applies to modules which load the mocked modules. + +ESM mocking is supported through `jest.unstable_mockModule`. As the name suggests, this API is still work in progress, please follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. + +The usage of `jest.unstable_mockModule` is essentially the same as `jest.mock` with two differences: the factory function is required and it can be sync or async: + +```js +import {jest} from '@jest/globals'; + +jest.unstable_mockModule('node:child_process', () => ({ + execSync: jest.fn(), + // etc. +})); + +const {execSync} = await import('node:child_process'); + +// etc. +``` + +For mocking CJS modules, you should continue to use `jest.mock`. See the example below: + +```js title="main.cjs" +const {BrowserWindow, app} = require('electron'); + +// etc. + +module.exports = {example}; +``` + +```js title="main.test.cjs" +import {createRequire} from 'node:module'; +import {jest} from '@jest/globals'; + +const require = createRequire(import.meta.url); + +jest.mock('electron', () => ({ + app: { + on: jest.fn(), + whenReady: jest.fn(() => Promise.resolve()), + }, + BrowserWindow: jest.fn().mockImplementation(() => ({ + // partial mocks. + })), +})); + +const {BrowserWindow} = require('electron'); +const exported = require('./main.cjs'); + +// alternatively +const {BrowserWindow} = (await import('electron')).default; +const exported = await import('./main.cjs'); + +// etc. +``` diff --git a/docs/ManualMocks.md b/docs/ManualMocks.md index 178226d727f9..c0d7ea2243ee 100644 --- a/docs/ManualMocks.md +++ b/docs/ManualMocks.md @@ -130,6 +130,12 @@ The code for this example is available at [examples/manual-mocks](https://github If you're using [ES module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) then you'll normally be inclined to put your `import` statements at the top of the test file. But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist `jest.mock` calls to the top of the module (before any imports). To learn more about this and see it in action, see [this repo](https://github.com/kentcdodds/how-jest-mocking-works). +:::caution + +`jest.mock` calls cannot be hoisted to the top of the module if you enabled ECMAScript modules support. The ESM module loader always evaluates the static imports before executing code. See [ECMAScriptModules](ECMAScriptModules.md) for details. + +::: + ## Mocking methods which are not implemented in JSDOM If some code uses a method which JSDOM (the DOM implementation used by Jest) hasn't implemented yet, testing it is not easily possible. This is e.g. the case with `window.matchMedia()`. Jest returns `TypeError: window.matchMedia is not a function` and doesn't properly execute the test. diff --git a/website/versioned_docs/version-25.x/ECMAScriptModules.md b/website/versioned_docs/version-25.x/ECMAScriptModules.md index 7c01cb606358..28cf24d550b0 100644 --- a/website/versioned_docs/version-25.x/ECMAScriptModules.md +++ b/website/versioned_docs/version-25.x/ECMAScriptModules.md @@ -7,7 +7,7 @@ Jest ships with _experimental_ support for ECMAScript Modules (ESM). > Note that due to its experimental nature there are many bugs and missing features in Jest's implementation, both known and unknown. You should check out the [tracking issue](https://github.com/facebook/jest/issues/9430) and the [label](https://github.com/facebook/jest/labels/ES%20Modules) on the issue tracker for the latest status. -> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `14.13.1`). +> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `18.8.0`). With the warnings out of the way, this is how you activate ESM support in your tests. @@ -32,4 +32,40 @@ jest.useFakeTimers(); // etc. ``` +Additionally, since ESM evaluates static `import` statements before looking at the code, the hoisting of `jest.mock` calls that happens in CJS won't work in ESM. To mock modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules - the same applies to modules which load the mocked modules. + +```js title="main.cjs" +const {BrowserWindow, app} = require('electron'); + +// etc. + +module.exports = {example}; +``` + +```js title="main.test.cjs" +import {createRequire} from 'node:module'; +import {jest} from '@jest/globals'; + +const require = createRequire(import.meta.url); + +jest.mock('electron', () => ({ + app: { + on: jest.fn(), + whenReady: jest.fn(() => Promise.resolve()), + }, + BrowserWindow: jest.fn().mockImplementation(() => ({ + // partial mocks. + })), +})); + +const {BrowserWindow} = require('electron'); +const exported = require('./main.cjs'); + +// alternatively +const {BrowserWindow} = (await import('electron')).default; +const exported = await import('./main.cjs'); + +// etc. +``` + Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. diff --git a/website/versioned_docs/version-25.x/ManualMocks.md b/website/versioned_docs/version-25.x/ManualMocks.md index 9387ca82fc5a..ae34120c8ec8 100644 --- a/website/versioned_docs/version-25.x/ManualMocks.md +++ b/website/versioned_docs/version-25.x/ManualMocks.md @@ -130,6 +130,12 @@ The code for this example is available at [examples/manual-mocks](https://github If you're using [ES module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) then you'll normally be inclined to put your `import` statements at the top of the test file. But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist `jest.mock` calls to the top of the module (before any imports). To learn more about this and see it in action, see [this repo](https://github.com/kentcdodds/how-jest-mocking-works). +:::caution + +`jest.mock` calls cannot be hoisted to the top of the module if you enabled ECMAScript modules support. The ESM module loader always evaluates the static imports before executing code. See [ECMAScriptModules](ECMAScriptModules.md) for details. + +::: + ## Mocking methods which are not implemented in JSDOM If some code uses a method which JSDOM (the DOM implementation used by Jest) hasn't implemented yet, testing it is not easily possible. This is e.g. the case with `window.matchMedia()`. Jest returns `TypeError: window.matchMedia is not a function` and doesn't properly execute the test. diff --git a/website/versioned_docs/version-26.x/ECMAScriptModules.md b/website/versioned_docs/version-26.x/ECMAScriptModules.md index 7c01cb606358..28cf24d550b0 100644 --- a/website/versioned_docs/version-26.x/ECMAScriptModules.md +++ b/website/versioned_docs/version-26.x/ECMAScriptModules.md @@ -7,7 +7,7 @@ Jest ships with _experimental_ support for ECMAScript Modules (ESM). > Note that due to its experimental nature there are many bugs and missing features in Jest's implementation, both known and unknown. You should check out the [tracking issue](https://github.com/facebook/jest/issues/9430) and the [label](https://github.com/facebook/jest/labels/ES%20Modules) on the issue tracker for the latest status. -> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `14.13.1`). +> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `18.8.0`). With the warnings out of the way, this is how you activate ESM support in your tests. @@ -32,4 +32,40 @@ jest.useFakeTimers(); // etc. ``` +Additionally, since ESM evaluates static `import` statements before looking at the code, the hoisting of `jest.mock` calls that happens in CJS won't work in ESM. To mock modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules - the same applies to modules which load the mocked modules. + +```js title="main.cjs" +const {BrowserWindow, app} = require('electron'); + +// etc. + +module.exports = {example}; +``` + +```js title="main.test.cjs" +import {createRequire} from 'node:module'; +import {jest} from '@jest/globals'; + +const require = createRequire(import.meta.url); + +jest.mock('electron', () => ({ + app: { + on: jest.fn(), + whenReady: jest.fn(() => Promise.resolve()), + }, + BrowserWindow: jest.fn().mockImplementation(() => ({ + // partial mocks. + })), +})); + +const {BrowserWindow} = require('electron'); +const exported = require('./main.cjs'); + +// alternatively +const {BrowserWindow} = (await import('electron')).default; +const exported = await import('./main.cjs'); + +// etc. +``` + Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. diff --git a/website/versioned_docs/version-26.x/ManualMocks.md b/website/versioned_docs/version-26.x/ManualMocks.md index 178226d727f9..c0d7ea2243ee 100644 --- a/website/versioned_docs/version-26.x/ManualMocks.md +++ b/website/versioned_docs/version-26.x/ManualMocks.md @@ -130,6 +130,12 @@ The code for this example is available at [examples/manual-mocks](https://github If you're using [ES module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) then you'll normally be inclined to put your `import` statements at the top of the test file. But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist `jest.mock` calls to the top of the module (before any imports). To learn more about this and see it in action, see [this repo](https://github.com/kentcdodds/how-jest-mocking-works). +:::caution + +`jest.mock` calls cannot be hoisted to the top of the module if you enabled ECMAScript modules support. The ESM module loader always evaluates the static imports before executing code. See [ECMAScriptModules](ECMAScriptModules.md) for details. + +::: + ## Mocking methods which are not implemented in JSDOM If some code uses a method which JSDOM (the DOM implementation used by Jest) hasn't implemented yet, testing it is not easily possible. This is e.g. the case with `window.matchMedia()`. Jest returns `TypeError: window.matchMedia is not a function` and doesn't properly execute the test. diff --git a/website/versioned_docs/version-27.x/ECMAScriptModules.md b/website/versioned_docs/version-27.x/ECMAScriptModules.md index b4ad17d411b4..576b645bfe11 100644 --- a/website/versioned_docs/version-27.x/ECMAScriptModules.md +++ b/website/versioned_docs/version-27.x/ECMAScriptModules.md @@ -7,7 +7,7 @@ Jest ships with _experimental_ support for ECMAScript Modules (ESM). > Note that due to its experimental nature there are many bugs and missing features in Jest's implementation, both known and unknown. You should check out the [tracking issue](https://github.com/facebook/jest/issues/9430) and the [label](https://github.com/facebook/jest/labels/ES%20Modules) on the issue tracker for the latest status. -> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `14.13.1`). +> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `18.8.0`). With the warnings out of the way, this is how you activate ESM support in your tests. @@ -33,4 +33,59 @@ jest.useFakeTimers(); // etc. ``` -Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. +## Module mocking in ESM + +Since ESM evaluates static `import` statements before looking at the code, the hoisting of `jest.mock` calls that happens in CJS won't work for ESM. To mock modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules - the same applies to modules which load the mocked modules. + +ESM mocking is supported through `jest.unstable_mockModule`. As the name suggests, this API is still work in progress, please follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. + +The usage of `jest.unstable_mockModule` is essentially the same as `jest.mock` with two differences: the factory function is required and it can be sync or async: + +```js +import {jest} from '@jest/globals'; + +jest.unstable_mockModule('node:child_process', () => ({ + execSync: jest.fn(), + // etc. +})); + +const {execSync} = await import('node:child_process'); + +// etc. +``` + +For mocking CJS modules, you should continue to use `jest.mock`. See the example below: + +```js title="main.cjs" +const {BrowserWindow, app} = require('electron'); + +// etc. + +module.exports = {example}; +``` + +```js title="main.test.cjs" +import {createRequire} from 'node:module'; +import {jest} from '@jest/globals'; + +const require = createRequire(import.meta.url); + +jest.mock('electron', () => ({ + app: { + on: jest.fn(), + whenReady: jest.fn(() => Promise.resolve()), + }, + BrowserWindow: jest.fn().mockImplementation(() => ({ + // partial mocks. + })), +})); + +const {BrowserWindow} = require('electron'); +const exported = require('./main.cjs'); + +// alternatively +const {BrowserWindow} = (await import('electron')).default; +const exported = await import('./main.cjs'); + +// etc. +``` diff --git a/website/versioned_docs/version-27.x/ManualMocks.md b/website/versioned_docs/version-27.x/ManualMocks.md index 178226d727f9..c0d7ea2243ee 100644 --- a/website/versioned_docs/version-27.x/ManualMocks.md +++ b/website/versioned_docs/version-27.x/ManualMocks.md @@ -130,6 +130,12 @@ The code for this example is available at [examples/manual-mocks](https://github If you're using [ES module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) then you'll normally be inclined to put your `import` statements at the top of the test file. But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist `jest.mock` calls to the top of the module (before any imports). To learn more about this and see it in action, see [this repo](https://github.com/kentcdodds/how-jest-mocking-works). +:::caution + +`jest.mock` calls cannot be hoisted to the top of the module if you enabled ECMAScript modules support. The ESM module loader always evaluates the static imports before executing code. See [ECMAScriptModules](ECMAScriptModules.md) for details. + +::: + ## Mocking methods which are not implemented in JSDOM If some code uses a method which JSDOM (the DOM implementation used by Jest) hasn't implemented yet, testing it is not easily possible. This is e.g. the case with `window.matchMedia()`. Jest returns `TypeError: window.matchMedia is not a function` and doesn't properly execute the test. diff --git a/website/versioned_docs/version-28.x/ECMAScriptModules.md b/website/versioned_docs/version-28.x/ECMAScriptModules.md index 199b7ff61b8c..d838c707248f 100644 --- a/website/versioned_docs/version-28.x/ECMAScriptModules.md +++ b/website/versioned_docs/version-28.x/ECMAScriptModules.md @@ -7,7 +7,7 @@ Jest ships with _experimental_ support for ECMAScript Modules (ESM). > Note that due to its experimental nature there are many bugs and missing features in Jest's implementation, both known and unknown. You should check out the [tracking issue](https://github.com/facebook/jest/issues/9430) and the [label](https://github.com/facebook/jest/labels/ES%20Modules) on the issue tracker for the latest status. -> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `14.13.1`). +> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `18.8.0`). With the warnings out of the way, this is how you activate ESM support in your tests. @@ -38,4 +38,59 @@ import.meta.jest.useFakeTimers(); // jest === import.meta.jest => true ``` -Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. +## Module mocking in ESM + +Since ESM evaluates static `import` statements before looking at the code, the hoisting of `jest.mock` calls that happens in CJS won't work for ESM. To mock modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules - the same applies to modules which load the mocked modules. + +ESM mocking is supported through `jest.unstable_mockModule`. As the name suggests, this API is still work in progress, please follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. + +The usage of `jest.unstable_mockModule` is essentially the same as `jest.mock` with two differences: the factory function is required and it can be sync or async: + +```js +import {jest} from '@jest/globals'; + +jest.unstable_mockModule('node:child_process', () => ({ + execSync: jest.fn(), + // etc. +})); + +const {execSync} = await import('node:child_process'); + +// etc. +``` + +For mocking CJS modules, you should continue to use `jest.mock`. See the example below: + +```js title="main.cjs" +const {BrowserWindow, app} = require('electron'); + +// etc. + +module.exports = {example}; +``` + +```js title="main.test.cjs" +import {createRequire} from 'node:module'; +import {jest} from '@jest/globals'; + +const require = createRequire(import.meta.url); + +jest.mock('electron', () => ({ + app: { + on: jest.fn(), + whenReady: jest.fn(() => Promise.resolve()), + }, + BrowserWindow: jest.fn().mockImplementation(() => ({ + // partial mocks. + })), +})); + +const {BrowserWindow} = require('electron'); +const exported = require('./main.cjs'); + +// alternatively +const {BrowserWindow} = (await import('electron')).default; +const exported = await import('./main.cjs'); + +// etc. +``` diff --git a/website/versioned_docs/version-28.x/ManualMocks.md b/website/versioned_docs/version-28.x/ManualMocks.md index 178226d727f9..c0d7ea2243ee 100644 --- a/website/versioned_docs/version-28.x/ManualMocks.md +++ b/website/versioned_docs/version-28.x/ManualMocks.md @@ -130,6 +130,12 @@ The code for this example is available at [examples/manual-mocks](https://github If you're using [ES module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) then you'll normally be inclined to put your `import` statements at the top of the test file. But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist `jest.mock` calls to the top of the module (before any imports). To learn more about this and see it in action, see [this repo](https://github.com/kentcdodds/how-jest-mocking-works). +:::caution + +`jest.mock` calls cannot be hoisted to the top of the module if you enabled ECMAScript modules support. The ESM module loader always evaluates the static imports before executing code. See [ECMAScriptModules](ECMAScriptModules.md) for details. + +::: + ## Mocking methods which are not implemented in JSDOM If some code uses a method which JSDOM (the DOM implementation used by Jest) hasn't implemented yet, testing it is not easily possible. This is e.g. the case with `window.matchMedia()`. Jest returns `TypeError: window.matchMedia is not a function` and doesn't properly execute the test. diff --git a/website/versioned_docs/version-29.0/ECMAScriptModules.md b/website/versioned_docs/version-29.0/ECMAScriptModules.md index 199b7ff61b8c..d838c707248f 100644 --- a/website/versioned_docs/version-29.0/ECMAScriptModules.md +++ b/website/versioned_docs/version-29.0/ECMAScriptModules.md @@ -7,7 +7,7 @@ Jest ships with _experimental_ support for ECMAScript Modules (ESM). > Note that due to its experimental nature there are many bugs and missing features in Jest's implementation, both known and unknown. You should check out the [tracking issue](https://github.com/facebook/jest/issues/9430) and the [label](https://github.com/facebook/jest/labels/ES%20Modules) on the issue tracker for the latest status. -> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `14.13.1`). +> Also note that the APIs Jest uses to implement ESM support is still [considered experimental by Node](https://nodejs.org/api/vm.html#vm_class_vm_module) (as of version `18.8.0`). With the warnings out of the way, this is how you activate ESM support in your tests. @@ -38,4 +38,59 @@ import.meta.jest.useFakeTimers(); // jest === import.meta.jest => true ``` -Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. +## Module mocking in ESM + +Since ESM evaluates static `import` statements before looking at the code, the hoisting of `jest.mock` calls that happens in CJS won't work for ESM. To mock modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules - the same applies to modules which load the mocked modules. + +ESM mocking is supported through `jest.unstable_mockModule`. As the name suggests, this API is still work in progress, please follow [this issue](https://github.com/facebook/jest/issues/10025) for updates. + +The usage of `jest.unstable_mockModule` is essentially the same as `jest.mock` with two differences: the factory function is required and it can be sync or async: + +```js +import {jest} from '@jest/globals'; + +jest.unstable_mockModule('node:child_process', () => ({ + execSync: jest.fn(), + // etc. +})); + +const {execSync} = await import('node:child_process'); + +// etc. +``` + +For mocking CJS modules, you should continue to use `jest.mock`. See the example below: + +```js title="main.cjs" +const {BrowserWindow, app} = require('electron'); + +// etc. + +module.exports = {example}; +``` + +```js title="main.test.cjs" +import {createRequire} from 'node:module'; +import {jest} from '@jest/globals'; + +const require = createRequire(import.meta.url); + +jest.mock('electron', () => ({ + app: { + on: jest.fn(), + whenReady: jest.fn(() => Promise.resolve()), + }, + BrowserWindow: jest.fn().mockImplementation(() => ({ + // partial mocks. + })), +})); + +const {BrowserWindow} = require('electron'); +const exported = require('./main.cjs'); + +// alternatively +const {BrowserWindow} = (await import('electron')).default; +const exported = await import('./main.cjs'); + +// etc. +``` diff --git a/website/versioned_docs/version-29.0/ManualMocks.md b/website/versioned_docs/version-29.0/ManualMocks.md index 178226d727f9..c0d7ea2243ee 100644 --- a/website/versioned_docs/version-29.0/ManualMocks.md +++ b/website/versioned_docs/version-29.0/ManualMocks.md @@ -130,6 +130,12 @@ The code for this example is available at [examples/manual-mocks](https://github If you're using [ES module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) then you'll normally be inclined to put your `import` statements at the top of the test file. But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist `jest.mock` calls to the top of the module (before any imports). To learn more about this and see it in action, see [this repo](https://github.com/kentcdodds/how-jest-mocking-works). +:::caution + +`jest.mock` calls cannot be hoisted to the top of the module if you enabled ECMAScript modules support. The ESM module loader always evaluates the static imports before executing code. See [ECMAScriptModules](ECMAScriptModules.md) for details. + +::: + ## Mocking methods which are not implemented in JSDOM If some code uses a method which JSDOM (the DOM implementation used by Jest) hasn't implemented yet, testing it is not easily possible. This is e.g. the case with `window.matchMedia()`. Jest returns `TypeError: window.matchMedia is not a function` and doesn't properly execute the test. diff --git a/website/versioned_sidebars/version-25.x-sidebars.json b/website/versioned_sidebars/version-25.x-sidebars.json index b390bdf1c162..c086e4e89978 100644 --- a/website/versioned_sidebars/version-25.x-sidebars.json +++ b/website/versioned_sidebars/version-25.x-sidebars.json @@ -66,6 +66,10 @@ "type": "doc", "id": "version-25.x/bypassing-module-mocks" }, + { + "type": "doc", + "id": "version-25.x/ecmascript-modules" + }, { "type": "doc", "id": "version-25.x/webpack"