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

docs: ESM update #13191

Merged
merged 14 commits into from Sep 3, 2022
33 changes: 32 additions & 1 deletion docs/ECMAScriptModules.md
Expand Up @@ -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.

Expand Down Expand Up @@ -38,4 +38,35 @@ import.meta.jest.useFakeTimers();
// jest === import.meta.jest => true
```

Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.
Copy link
Member

@SimenB SimenB Sep 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we talk about "dynamic import()", and then go on to use require?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made the change to also mention require there, with the example now showing both require and dynamic import() usage. Personally I prefer require for CJS modules but I think it's better to show both on the docs so the users aren't going to think that either is more preferable.


```js
// - main.cjs
iamWing marked this conversation as resolved.
Show resolved Hide resolved
const { BrowserWindow, app } = require('electron');

// etc.

module.exports = { example };
```

```js
// - main.test.js
iamWing marked this conversation as resolved.
Show resolved Hide resolved
import { jest } from '@jest/globals';

jest.mock('electron', () => ({
iamWing marked this conversation as resolved.
Show resolved Hide resolved
app: {
on: jest.fn(),
whenReady: jest.fn(() => Promise.resolve()),
},
BrowserWindow: jest.fn().mockImplementation(() => ({
// partial mocks.
}))
}));

const { BrowserWindow } = (await import('electron')).default;
iamWing marked this conversation as resolved.
Show resolved Hide resolved
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.
2 changes: 2 additions & 0 deletions docs/ManualMocks.md
Expand Up @@ -130,6 +130,8 @@ 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 does NOT hoist `jest.mock` calls to the top of the module if you have ESM support activated. See [ECMAScriptModules](ECMAScriptModules.md) for details.*
iamWing marked this conversation as resolved.
Show resolved Hide resolved

## 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.
Expand Down
33 changes: 32 additions & 1 deletion website/versioned_docs/version-25.x/ECMAScriptModules.md
Expand Up @@ -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.

Expand All @@ -32,4 +32,35 @@ jest.useFakeTimers();
// etc.
```

Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.

```js
// - main.cjs
const { BrowserWindow, app } = require('electron');

// etc.

module.exports = { example };
```

```js
// - main.test.js
import { jest } from '@jest/globals';

jest.mock('electron', () => ({
app: {
on: jest.fn(),
whenReady: jest.fn(() => Promise.resolve()),
},
BrowserWindow: jest.fn().mockImplementation(() => ({
// partial mocks.
}))
}));

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.
2 changes: 2 additions & 0 deletions website/versioned_docs/version-25.x/ManualMocks.md
Expand Up @@ -130,6 +130,8 @@ 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 does NOT hoist `jest.mock` calls to the top of the module if you have ESM support activated. 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.
Expand Down
33 changes: 32 additions & 1 deletion website/versioned_docs/version-26.x/ECMAScriptModules.md
Expand Up @@ -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.

Expand All @@ -32,4 +32,35 @@ jest.useFakeTimers();
// etc.
```

Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.

```js
// - main.cjs
const { BrowserWindow, app } = require('electron');

// etc.

module.exports = { example };
```

```js
// - main.test.js
import { jest } from '@jest/globals';

jest.mock('electron', () => ({
app: {
on: jest.fn(),
whenReady: jest.fn(() => Promise.resolve()),
},
BrowserWindow: jest.fn().mockImplementation(() => ({
// partial mocks.
}))
}));

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.
2 changes: 2 additions & 0 deletions website/versioned_docs/version-26.x/ManualMocks.md
Expand Up @@ -130,6 +130,8 @@ 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 does NOT hoist `jest.mock` calls to the top of the module if you have ESM support activated. 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.
Expand Down
33 changes: 32 additions & 1 deletion website/versioned_docs/version-27.x/ECMAScriptModules.md
Expand Up @@ -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.

Expand All @@ -33,4 +33,35 @@ jest.useFakeTimers();
// etc.
```

Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.

```js
// - main.cjs
const { BrowserWindow, app } = require('electron');

// etc.

module.exports = { example };
```

```js
// - main.test.js
import { jest } from '@jest/globals';

jest.mock('electron', () => ({
app: {
on: jest.fn(),
whenReady: jest.fn(() => Promise.resolve()),
},
BrowserWindow: jest.fn().mockImplementation(() => ({
// partial mocks.
}))
}));

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.
2 changes: 2 additions & 0 deletions website/versioned_docs/version-27.x/ManualMocks.md
Expand Up @@ -130,6 +130,8 @@ 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 does NOT hoist `jest.mock` calls to the top of the module if you have ESM support activated. 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.
Expand Down
33 changes: 32 additions & 1 deletion website/versioned_docs/version-28.x/ECMAScriptModules.md
Expand Up @@ -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.

Expand Down Expand Up @@ -38,4 +38,35 @@ import.meta.jest.useFakeTimers();
// jest === import.meta.jest => true
```

Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.

```js
// - main.cjs
const { BrowserWindow, app } = require('electron');

// etc.

module.exports = { example };
```

```js
// - main.test.js
import { jest } from '@jest/globals';

jest.mock('electron', () => ({
app: {
on: jest.fn(),
whenReady: jest.fn(() => Promise.resolve()),
},
BrowserWindow: jest.fn().mockImplementation(() => ({
// partial mocks.
}))
}));

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.
2 changes: 2 additions & 0 deletions website/versioned_docs/version-28.x/ManualMocks.md
Expand Up @@ -130,6 +130,8 @@ 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 does NOT hoist `jest.mock` calls to the top of the module if you have ESM support activated. 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.
Expand Down
33 changes: 32 additions & 1 deletion website/versioned_docs/version-29.0/ECMAScriptModules.md
Expand Up @@ -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.

Expand Down Expand Up @@ -38,4 +38,35 @@ import.meta.jest.useFakeTimers();
// jest === import.meta.jest => true
```

Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.

```js
// - main.cjs
const { BrowserWindow, app } = require('electron');

// etc.

module.exports = { example };
```

```js
// - main.test.js
import { jest } from '@jest/globals';

jest.mock('electron', () => ({
app: {
on: jest.fn(),
whenReady: jest.fn(() => Promise.resolve()),
},
BrowserWindow: jest.fn().mockImplementation(() => ({
// partial mocks.
}))
}));

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.
2 changes: 2 additions & 0 deletions website/versioned_docs/version-29.0/ManualMocks.md
Expand Up @@ -130,6 +130,8 @@ 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 does NOT hoist `jest.mock` calls to the top of the module if you have ESM support activated. 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.
Expand Down