Skip to content

Commit a50b969

Browse files
authored
docs: add migration guide to v30 (#15556) (#15612)
1 parent 57a0ef1 commit a50b969

File tree

2 files changed

+232
-1
lines changed

2 files changed

+232
-1
lines changed

docs/UpgradingToJest30.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
---
2+
id: upgrading-to-jest30
3+
title: From v29 to v30
4+
---
5+
6+
Upgrading Jest from v29 to v30? This guide aims to help refactoring your configuration and tests.
7+
8+
:::info
9+
10+
See [changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md#3000) for the full list of changes.
11+
12+
:::
13+
14+
:::note
15+
16+
Upgrading from an older version? You can see the upgrade guide from v28 to v29 [here](/docs/upgrading-to-jest29).
17+
18+
:::
19+
20+
## Compatibility
21+
22+
- Jest 30 drops support for Node 14, 16, 19, and 21. The minimum supported Node versions are now 18.x. Ensure your environment is using a compatible Node release before upgrading.
23+
- The minimum TypeScript version is now 5.0. Support for TypeScript 4.3 and below has been removed. Update your TypeScript dependency to v5+ if you use TypeScript with Jest.
24+
- The `jest-environment-jsdom` package now uses JSDOM v22. This upgrade may introduce behavior changes in the DOM environment. If you encounter differences in DOM behavior or new warnings, refer to the JSDOM release notes for [v21–22](https://github.com/jsdom/jsdom/compare/21.0.0...22.0.0).
25+
26+
## Jest Expect & Matchers
27+
28+
### Removal of Alias Matcher Functions
29+
30+
All _alias_ matcher names have been removed in favor of their primary names. If you have been using older, deprecated matcher names, you will need to update your tests:
31+
32+
- **Removed aliases and their replacements:**
33+
- `expect(fn).toBeCalled()` **** `expect(fn).toHaveBeenCalled()`
34+
- `expect(fn).toBeCalledTimes(n)` **** `expect(fn).toHaveBeenCalledTimes(n)`
35+
- `expect(fn).toBeCalledWith(arg)` **** `expect(fn).toHaveBeenCalledWith(arg)`
36+
- `expect(fn).lastCalledWith(arg)` **** `expect(fn).toHaveBeenLastCalledWith(arg)`
37+
- `expect(fn).nthCalledWith(n, arg)` **** `expect(fn).toHaveBeenNthCalledWith(n, arg)`
38+
- `expect(fn).toReturn()` **** `expect(fn).toHaveReturned()`
39+
- `expect(fn).toReturnTimes(n)` **** `expect(fn).toHaveReturnedTimes(n)`
40+
- `expect(fn).toReturnWith(val)` **** `expect(fn).toHaveReturnedWith(val)`
41+
- `expect(fn).lastReturnedWith(val)` **** `expect(fn).toHaveLastReturnedWith(val)`
42+
- `expect(fn).nthReturnedWith(n, val)` **** `expect(fn).toHaveNthReturnedWith(n, val)`
43+
- `expect(func).toThrowError(message)` **** `expect(func).toThrow(message)`
44+
45+
:::info
46+
47+
These alias methods were deprecated since Jest 26, and in Jest 30 they are fully removed. Perform a global search-and-replace in your codebase to update to the canonical matcher names. The functionality is identical — only the method names have changed. (If you use ESLint with `eslint-plugin-jest`, the [`no-alias-methods`](https://github.com/jest-community/eslint-plugin-jest/blob/HEAD/docs/rules/no-alias-methods.md) rule can help automate this replacement.)
48+
49+
:::
50+
51+
### Non-enumerable properties
52+
53+
Non-enumerable object properties are now excluded from object matchers by default. This could affect `expect.objectContaining` or equality checks.
54+
55+
### Improved Type Inference for CalledWith
56+
57+
TypeScript users: The types for the `CalledWith` family of matchers (e.g. `toHaveBeenCalledWith`) have been improved to infer function parameter types. In most cases this will catch type mismatches more accurately. This is a **compile-time** breaking change.
58+
59+
If you were asserting calls with arguments that don’t match the actual function’s parameter types, TypeScript may now error on those tests. For example, if a function is typed to accept a number and you wrote `expect(fn).toHaveBeenCalledWith("string")`, TypeScript 5 + Jest 30’s types will flag this. The runtime behavior of the matcher is unchanged.
60+
61+
To fix new TypeScript errors, ensure your test arguments align with the function’s expected types (or use type casts if you intentionally call with different types).
62+
63+
This change doesn’t impact runtime, but it can surface new type errors in your tests that were previously unnoticed, making your tests more type-safe.
64+
65+
## Configuration Updates
66+
67+
### Support for `.mts` and `.cts` File Extensions
68+
69+
Jest 30 expands support for ESM and TypeScript module file extensions:
70+
71+
- The default `moduleFileExtensions` now include `.mts` and `.cts` (TypeScript ESM and CommonJS modules) in addition to the usual extensions.
72+
- The default `testMatch` and `testRegex` patterns have been updated to recognize `.mjs`, `.cjs`, `.mts`, and `.cts` files as test files.
73+
74+
:::info
75+
76+
If your project contains files with these extensions that are **not** intended to be treated as modules or tests, you may need to adjust your configuration. Conversely, if you have test files with these extensions, Jest will now detect them by default (you may remove custom configuration that was previously needed to include them).
77+
78+
:::
79+
80+
### `testPathPattern` Renamed to `testPathPatterns`
81+
82+
If you filter tests by path, note that the configuration option and CLI flag have changed:
83+
84+
- **Configuration:** The `testPathPattern` option (singular) has been replaced by `testPathPatterns` (plural). Instead of a single regex string, this option now takes an array of patterns. For example:
85+
86+
Jest 29 configuration:
87+
88+
```js
89+
export default {
90+
testPathPattern: 'e2e/.*\\.spec\\.js',
91+
};
92+
```
93+
94+
Jest 30 configuration:
95+
96+
```js
97+
export default {
98+
testPathPatterns: ['e2e/.*\\.spec\\.js'],
99+
};
100+
```
101+
102+
Each pattern in the array is treated as a regex or glob to match test file paths.
103+
104+
- **CLI usage:** The `--testPathPattern` flag is now `--testPathPatterns`. You can pass multiple patterns by separating them with spaces or by repeating the flag. For example:
105+
106+
```bash
107+
# Old (Jest 29)
108+
jest --testPathPattern="unit/.*"
109+
110+
# New (Jest 30)
111+
jest --testPathPatterns "unit/.*" "integration/.*"
112+
```
113+
114+
Internally, Jest consolidates these patterns into a `TestPathPatterns` object. If you were programmatically calling Jest’s watch mode with a `testPathPattern`, you must now construct a `TestPathPatterns` instance instead.
115+
116+
### Removed `--init` Command
117+
118+
The interactive config initialization command `jest --init` has been **removed**. This deprecated command was used to scaffold a Jest configuration file. If you need to create a config, you can run:
119+
120+
```bash
121+
npm init jest@latest
122+
# Or for Yarn
123+
yarn create jest
124+
# Or for pnpm
125+
pnpm create jest
126+
```
127+
128+
### Other CLI Changes
129+
130+
- Jest now validates CLI flags that require arguments to ensure an argument is provided. For example, if you use `--maxWorkers` or `--selectProjects`, you must include a value (e.g. `--maxWorkers=50%`). Previously, Jest might have allowed certain flags without a value (falling back to defaults); now it will throw an error if the value is missing. Ensure any scripts or npm commands passing Jest flags include the necessary arguments.
131+
- If you use the `--filter` option to filter test files (an advanced use-case where you provide a path to a filter implementation), the expected interface has changed. The filter function should now return an object of shape `{filtered: Array<string>}`, matching the documented format. In prior versions, a different return format may have been accepted (e.g., returning an array directly). Update any custom test filter functions to return an object with a `filtered` property as documented.
132+
133+
## Test Runner Behavior Changes
134+
135+
### Unhandled Promise Rejections in Tests
136+
137+
Jest includes a fix to properly handle promises that are rejected and later caught, to avoid false test failures. In Jest 29, a promise rejection that was handled asynchronously (after the test tick) could still cause the test to fail erroneously. Jest 30 now waits an extra event loop turn to confirm that a promise rejection remains unhandled before failing a test.
138+
139+
:::info
140+
141+
You should see fewer false positives for unhandled promise rejections. Tests that previously failed due to async handled rejections should now pass. However, this change can slightly slow down test completion, especially in tests that intentionally reject promises. To mitigate performance impact, a new configuration flag `waitNextEventLoopTurnForUnhandledRejectionEvents` was introduced. This flag, when disabled, can restore the previous behavior (not waiting) if absolutely needed. Most users should not need to change this – the default now favors correctness by preventing false failures.
142+
143+
:::
144+
145+
### Custom Test Sequencers
146+
147+
If you have a **custom test sequencer** (a class inheriting from Jest’s `TestSequencer`), you’ll need to update it for Jest 30. Jest now passes additional context to the test sequencer. Specifically, the `TestSequencer` API was extended to expose the `globalConfig` and `contexts` to your sequencer.
148+
149+
### Required `globalConfig` in Runtime
150+
151+
For those using Jest’s programmatic APIs: constructing a `Runtime` now requires a `globalConfig` parameter. If you use `jest.runCLI` or similar helpers, make sure you pass all required options as per the updated API. (The typical `jest` CLI or `npm test` usage is unaffected by this change.)
152+
153+
## Snapshots and Output Changes
154+
155+
### Update broken documentation link
156+
157+
Deprecated goo.gl URL is removed from snapshot tests. This change updates existing snapshots to replace any goo.gl links with full, unshortened URLs.
158+
159+
### Error Causes in Snapshots
160+
161+
Error serialization in snapshots has changed. Jest 30’s snapshot serializer will now include an `Error`’s **`cause`** property (if present) when printing errors.
162+
163+
### React Empty String Rendering
164+
165+
The React-specific snapshot serializer no longer renders empty string children (`""`) in the output. In Jest 29, an empty string child in a React element might appear as `""` in the snapshot output; in Jest 30 it will be omitted (treated as no content).
166+
167+
### Improved Object Printing in `pretty-format`
168+
169+
`ArrayBuffer` and `DataView` are now printed in a human-readable way instead of as objects with internal fields.
170+
171+
## Jest Mock API Changes
172+
173+
### `jest.genMockFromModule` Removed
174+
175+
The legacy function `jest.genMockFromModule(moduleName)` has been removed. It was previously deprecated in favor of `jest.createMockFromModule(moduleName)`. If you still use `genMockFromModule`, switch to `createMockFromModule` – the behavior is the same. For example:
176+
177+
Old code (Jest 29):
178+
179+
```js
180+
const mockFs = jest.genMockFromModule('fs');
181+
```
182+
183+
New code (Jest 30):
184+
185+
```js
186+
const mockFs = jest.createMockFromModule('fs');
187+
```
188+
189+
### Removed Mock Function Types
190+
191+
Some TypeScript types related to mock functions have been removed from the public API.
192+
193+
- `MockFunctionMetadata`
194+
- `MockFunctionMetadataType`
195+
- `SpyInstance`
196+
197+
If you were using `jest.SpyInstance` in your TypeScript code (for instance, to annotate the return of `jest.spyOn`), you should update to using `jest.Mock` or the more specific `jest.MockedFunction` types.
198+
199+
:::note
200+
201+
These type removals do not affect runtime behavior – they are only relevant for TypeScript users. JavaScript users or tests will not notice any difference.
202+
203+
:::
204+
205+
## Module & Runtime Changes
206+
207+
### ESM Module Support and Internal Restructuring
208+
209+
Jest has introduced significant under-the-hood changes to how its packages are bundled and exported:
210+
211+
- All of Jest’s internal modules are now bundled into single files for faster startup. This means when you install Jest, the number of files it loads is greatly reduced (improving performance). However, a side effect is that any unofficial deep imports into Jest’s packages will likely break. For example, if you previously did something like `require('jest-runner/build/testWorker')` (which is not a public API), this path will no longer exist. **Solution:** Use Jest’s public APIs or documented interfaces only. If you are relying on an internal module that you think should be part of the public API, please open a Pull Request to expose it.
212+
- Jest’s packages now provide ESM wrappers. This is part of ongoing work to allow running Jest in an ESM context. All official Jest packages export themselves properly via the `package.json` `"exports"` field. For most users, this has no direct impact – you continue to use Jest the same way. But if you maintain a tool or plugin that imports Jest’s modules, ensure you use the package names as imports (which will resolve via Node’s module resolution).
213+
214+
These changes are considered breaking for anyone poking at Jest’s internals, but **not** for typical usage of the Jest CLI and config. After upgrading, run your tests normally – if you get module resolution errors related to Jest’s own modules, it’s likely due to an unsupported import that needs to be removed or updated.
215+
216+
### Glob Pattern Matching Changes
217+
218+
Jest’s dependency for file pattern matching (`glob`) has been upgraded to v10. Glob v10 may have slight differences in pattern syntax and behavior.
219+
220+
One notable change is that `glob@10` treats brace expansions and extglobs a bit differently and is stricter about some patterns. If you have custom `testMatch` patterns, `moduleNameMapper` patterns, or other glob-based config, they should continue to work in most cases. Just be aware that if a pattern isn’t matching files as it used to, you might need to adjust it for the new glob engine.
221+
222+
## Conclusion
223+
224+
Upgrade to Jest 30 by first ensuring your environment meets the new Node.js and TypeScript requirements. Update your Jest configuration file and CLI usage for the renamed and removed options (notably `testPathPatterns` and the removal of `--init`). Run your test suite and address any failures:
225+
226+
- Fix tests using removed matcher aliases by replacing them with the official matcher names.
227+
- Update any snapshots that fail due to the formatting changes (error causes, empty strings, etc.).
228+
- Pay attention to TypeScript compiler errors – they will guide you to update deprecated API usage (like `genMockFromModule` or removed types) and adjust tests where types are now stricter.
229+
230+
Happy testing!

website/sidebars.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"testing-frameworks"
3535
],
3636
"Upgrade Guides": [
37-
"upgrading-to-jest29"
37+
"upgrading-to-jest29",
38+
"upgrading-to-jest30"
3839
]
3940
},
4041
"api": [

0 commit comments

Comments
 (0)