Skip to content

Commit 2f4340c

Browse files
authored
feat(@jest/globals): add jest.Mocked, jest.MockedClass, jest.MockedFunction and jest.MockedObject utility types (#12727)
1 parent 760dd21 commit 2f4340c

7 files changed

Lines changed: 94 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- `[jest-config]` [**BREAKING**] Make `snapshotFormat` default to `escapeString: false` and `printBasicPrototype: false` ([#13036](https://github.com/facebook/jest/pull/13036))
66
- `[jest-environment-jsdom]` [**BREAKING**] Upgrade to `jsdom@20` ([#13037](https://github.com/facebook/jest/pull/13037), [#13058](https://github.com/facebook/jest/pull/13058))
7+
- `[@jest/globals]` Add `jest.Mocked`, `jest.MockedClass`, `jest.MockedFunction` and `jest.MockedObject` utility types ([#12727](https://github.com/facebook/jest/pull/12727))
78
- `[jest-mock]` [**BREAKING**] Refactor `Mocked*` utility types. `MaybeMockedDeep` and `MaybeMocked` became `Mocked` and `MockedShallow` respectively; only deep mocked variants of `MockedClass`, `MockedFunction` and `MockedObject` are exported ([#13123](https://github.com/facebook/jest/pull/13123), [#13124](https://github.com/facebook/jest/pull/13124))
89
- `[jest-worker]` Adds `workerIdleMemoryLimit` option which is used as a check for worker memory leaks >= Node 16.11.0 and recycles child workers as required. ([#13056](https://github.com/facebook/jest/pull/13056), [#13105](https://github.com/facebook/jest/pull/13105), [#13106](https://github.com/facebook/jest/pull/13106), [#13107](https://github.com/facebook/jest/pull/13107))
910
- `[pretty-format]` [**BREAKING**] Remove `ConvertAnsi` plugin in favour of `jest-serializer-ansi-escapes` ([#13040](https://github.com/facebook/jest/pull/13040))

docs/MockFunctionAPI.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,28 @@ test('calculate calls add', () => {
520520
expect(mockAdd).toBeCalledWith(1, 2);
521521
});
522522
```
523+
524+
### `jest.Mocked<Source>`
525+
526+
The `jest.Mocked<Source>` utility type returns the `Source` type wrapped with type definitions of Jest mock function.
527+
528+
```ts
529+
import fetch from 'node-fetch';
530+
import {expect, jest, test} from '@jest/globals';
531+
532+
jest.mock('node-fetch');
533+
534+
let mockedFetch: jest.Mocked<typeof fetch>;
535+
536+
test('makes correct call', () => {
537+
mockedFetch = getMockedFetch();
538+
// ...
539+
});
540+
541+
test('returns correct data', () => {
542+
mockedFetch = getMockedFetch();
543+
// ...
544+
});
545+
```
546+
547+
Types of classes, functions or objects can be passed as type argument to `jest.Mocked<Source>`. If you prefer to constrain the input type, use: `jest.MockedClass<Source>`, `jest.MockedFunction<Source>` or `jest.MockedObject<Source>`.

packages/jest-globals/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"dependencies": {
2323
"@jest/environment": "workspace:^",
2424
"@jest/expect": "workspace:^",
25-
"@jest/types": "workspace:^"
25+
"@jest/types": "workspace:^",
26+
"jest-mock": "workspace:^"
2627
},
2728
"publishConfig": {
2829
"access": "public"

packages/jest-globals/src/index.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@
88
import type {Jest} from '@jest/environment';
99
import type {JestExpect} from '@jest/expect';
1010
import type {Global} from '@jest/types';
11-
12-
export declare const jest: Jest;
11+
import type {
12+
ClassLike,
13+
FunctionLike,
14+
Mocked as JestMocked,
15+
MockedClass as JestMockedClass,
16+
MockedFunction as JestMockedFunction,
17+
MockedObject as JestMockedObject,
18+
} from 'jest-mock';
1319

1420
export declare const expect: JestExpect;
1521

@@ -26,6 +32,30 @@ export declare const beforeEach: Global.GlobalAdditions['beforeEach'];
2632
export declare const afterEach: Global.GlobalAdditions['afterEach'];
2733
export declare const afterAll: Global.GlobalAdditions['afterAll'];
2834

35+
declare const jest: Jest;
36+
37+
// eslint-disable-next-line @typescript-eslint/no-namespace
38+
declare namespace jest {
39+
/**
40+
* Wraps a class, function or object type with Jest mock type definitions.
41+
*/
42+
export type Mocked<T extends object> = JestMocked<T>;
43+
/**
44+
* Wraps a class type with Jest mock type definitions.
45+
*/
46+
export type MockedClass<T extends ClassLike> = JestMockedClass<T>;
47+
/**
48+
* Wraps a function type with Jest mock type definitions.
49+
*/
50+
export type MockedFunction<T extends FunctionLike> = JestMockedFunction<T>;
51+
/**
52+
* Wraps an object type with Jest mock type definitions.
53+
*/
54+
export type MockedObject<T extends object> = JestMockedObject<T>;
55+
}
56+
57+
export {jest};
58+
2959
throw new Error(
3060
'Do not import `@jest/globals` outside of the Jest test environment',
3161
);

packages/jest-globals/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"references": [
1212
{"path": "../jest-environment"},
1313
{"path": "../jest-expect"},
14+
{"path": "../jest-mock"},
1415
{"path": "../jest-types"}
1516
]
1617
}

packages/jest-types/__typetests__/jest.test.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77

88
import {expectAssignable, expectError, expectType} from 'tsd-lite';
99
import {jest} from '@jest/globals';
10-
import type {Mock, ModuleMocker, SpyInstance} from 'jest-mock';
10+
import type {
11+
Mock,
12+
Mocked,
13+
MockedClass,
14+
MockedFunction,
15+
MockedObject,
16+
ModuleMocker,
17+
SpyInstance,
18+
} from 'jest-mock';
1119

1220
expectType<typeof jest>(
1321
jest
@@ -210,7 +218,7 @@ expectType<ModuleMocker['fn']>(jest.fn);
210218

211219
expectType<ModuleMocker['spyOn']>(jest.spyOn);
212220

213-
// deep mocked()
221+
// Mocked*<T>
214222

215223
class SomeClass {
216224
constructor(one: string, two?: boolean) {}
@@ -223,6 +231,10 @@ class SomeClass {
223231
}
224232
}
225233

234+
function someFunction(a: string, b?: number): boolean {
235+
return true;
236+
}
237+
226238
const someObject = {
227239
SomeClass,
228240

@@ -248,6 +260,24 @@ const someObject = {
248260
someClassInstance: new SomeClass('value'),
249261
};
250262

263+
expectType<Mocked<typeof someObject>>(
264+
someObject as jest.Mocked<typeof someObject>,
265+
);
266+
267+
expectType<MockedClass<typeof SomeClass>>(
268+
SomeClass as jest.MockedClass<typeof SomeClass>,
269+
);
270+
271+
expectType<MockedFunction<typeof someFunction>>(
272+
someFunction as jest.MockedFunction<typeof someFunction>,
273+
);
274+
275+
expectType<MockedObject<typeof someObject>>(
276+
someObject as jest.MockedObject<typeof someObject>,
277+
);
278+
279+
// deep mocked()
280+
251281
const mockObjectA = jest.mocked(someObject, true);
252282

253283
expectError(jest.mocked('abc', true));

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,6 +2717,7 @@ __metadata:
27172717
"@jest/environment": "workspace:^"
27182718
"@jest/expect": "workspace:^"
27192719
"@jest/types": "workspace:^"
2720+
jest-mock: "workspace:^"
27202721
languageName: unknown
27212722
linkType: soft
27222723

0 commit comments

Comments
 (0)