Skip to content

Commit

Permalink
feat(@jest/globals): add jest.Mocked, jest.MockedClass, `jest.Moc…
Browse files Browse the repository at this point in the history
…kedFunction` and `jest.MockedObject` utility types (#12727)
  • Loading branch information
mrazauskas committed Aug 12, 2022
1 parent 760dd21 commit 2f4340c
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

- `[jest-config]` [**BREAKING**] Make `snapshotFormat` default to `escapeString: false` and `printBasicPrototype: false` ([#13036](https://github.com/facebook/jest/pull/13036))
- `[jest-environment-jsdom]` [**BREAKING**] Upgrade to `jsdom@20` ([#13037](https://github.com/facebook/jest/pull/13037), [#13058](https://github.com/facebook/jest/pull/13058))
- `[@jest/globals]` Add `jest.Mocked`, `jest.MockedClass`, `jest.MockedFunction` and `jest.MockedObject` utility types ([#12727](https://github.com/facebook/jest/pull/12727))
- `[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))
- `[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))
- `[pretty-format]` [**BREAKING**] Remove `ConvertAnsi` plugin in favour of `jest-serializer-ansi-escapes` ([#13040](https://github.com/facebook/jest/pull/13040))
Expand Down
25 changes: 25 additions & 0 deletions docs/MockFunctionAPI.md
Expand Up @@ -520,3 +520,28 @@ test('calculate calls add', () => {
expect(mockAdd).toBeCalledWith(1, 2);
});
```

### `jest.Mocked<Source>`

The `jest.Mocked<Source>` utility type returns the `Source` type wrapped with type definitions of Jest mock function.

```ts
import fetch from 'node-fetch';
import {expect, jest, test} from '@jest/globals';

jest.mock('node-fetch');

let mockedFetch: jest.Mocked<typeof fetch>;

test('makes correct call', () => {
mockedFetch = getMockedFetch();
// ...
});

test('returns correct data', () => {
mockedFetch = getMockedFetch();
// ...
});
```

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>`.
3 changes: 2 additions & 1 deletion packages/jest-globals/package.json
Expand Up @@ -22,7 +22,8 @@
"dependencies": {
"@jest/environment": "workspace:^",
"@jest/expect": "workspace:^",
"@jest/types": "workspace:^"
"@jest/types": "workspace:^",
"jest-mock": "workspace:^"
},
"publishConfig": {
"access": "public"
Expand Down
34 changes: 32 additions & 2 deletions packages/jest-globals/src/index.ts
Expand Up @@ -8,8 +8,14 @@
import type {Jest} from '@jest/environment';
import type {JestExpect} from '@jest/expect';
import type {Global} from '@jest/types';

export declare const jest: Jest;
import type {
ClassLike,
FunctionLike,
Mocked as JestMocked,
MockedClass as JestMockedClass,
MockedFunction as JestMockedFunction,
MockedObject as JestMockedObject,
} from 'jest-mock';

export declare const expect: JestExpect;

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

declare const jest: Jest;

// eslint-disable-next-line @typescript-eslint/no-namespace
declare namespace jest {
/**
* Wraps a class, function or object type with Jest mock type definitions.
*/
export type Mocked<T extends object> = JestMocked<T>;
/**
* Wraps a class type with Jest mock type definitions.
*/
export type MockedClass<T extends ClassLike> = JestMockedClass<T>;
/**
* Wraps a function type with Jest mock type definitions.
*/
export type MockedFunction<T extends FunctionLike> = JestMockedFunction<T>;
/**
* Wraps an object type with Jest mock type definitions.
*/
export type MockedObject<T extends object> = JestMockedObject<T>;
}

export {jest};

throw new Error(
'Do not import `@jest/globals` outside of the Jest test environment',
);
1 change: 1 addition & 0 deletions packages/jest-globals/tsconfig.json
Expand Up @@ -11,6 +11,7 @@
"references": [
{"path": "../jest-environment"},
{"path": "../jest-expect"},
{"path": "../jest-mock"},
{"path": "../jest-types"}
]
}
34 changes: 32 additions & 2 deletions packages/jest-types/__typetests__/jest.test.ts
Expand Up @@ -7,7 +7,15 @@

import {expectAssignable, expectError, expectType} from 'tsd-lite';
import {jest} from '@jest/globals';
import type {Mock, ModuleMocker, SpyInstance} from 'jest-mock';
import type {
Mock,
Mocked,
MockedClass,
MockedFunction,
MockedObject,
ModuleMocker,
SpyInstance,
} from 'jest-mock';

expectType<typeof jest>(
jest
Expand Down Expand Up @@ -210,7 +218,7 @@ expectType<ModuleMocker['fn']>(jest.fn);

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

// deep mocked()
// Mocked*<T>

class SomeClass {
constructor(one: string, two?: boolean) {}
Expand All @@ -223,6 +231,10 @@ class SomeClass {
}
}

function someFunction(a: string, b?: number): boolean {
return true;
}

const someObject = {
SomeClass,

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

expectType<Mocked<typeof someObject>>(
someObject as jest.Mocked<typeof someObject>,
);

expectType<MockedClass<typeof SomeClass>>(
SomeClass as jest.MockedClass<typeof SomeClass>,
);

expectType<MockedFunction<typeof someFunction>>(
someFunction as jest.MockedFunction<typeof someFunction>,
);

expectType<MockedObject<typeof someObject>>(
someObject as jest.MockedObject<typeof someObject>,
);

// deep mocked()

const mockObjectA = jest.mocked(someObject, true);

expectError(jest.mocked('abc', true));
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Expand Up @@ -2717,6 +2717,7 @@ __metadata:
"@jest/environment": "workspace:^"
"@jest/expect": "workspace:^"
"@jest/types": "workspace:^"
jest-mock: "workspace:^"
languageName: unknown
linkType: soft

Expand Down

0 comments on commit 2f4340c

Please sign in to comment.