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

feat(@jest/globals, jest-mock): add jest.Spied* utility types #13440

Merged
merged 14 commits into from
Oct 16, 2022
Merged

feat(@jest/globals, jest-mock): add jest.Spied* utility types #13440

merged 14 commits into from
Oct 16, 2022

Conversation

mrazauskas
Copy link
Contributor

@mrazauskas mrazauskas commented Oct 14, 2022

Summary

@types/jest provides jest.SpyInstance<T> and jest.SpiedFunction<T> utility types. Jest currently does not exposed these on the jest namespace.

Note that jest.SpyInstance<T> works only on methods, but can’t be used on class constructors, getters and setters. It is equal to jest.SpiedFunction<T> only that jest.SpyInstance<T> takes two type arguments instead of one.

To cover more use cases, I created jest.SpiedClass<T>, jest.SpiedFunction<T>, jest.SpiedGetter<T>, jest.SpiedSetter<T>. Names are similar to jest.Mocked* utilities.

jest.Mocked<T> is very smart type. I wanted to have somewhat similar jest.Spied<T>. It works only with classes and functions, because there is no way to differentiate between a getter and a setter. I mean, either of them would simply have type of string or number not a function signature. Hence user will have to use jest.SpiedGetter<T> or jest.SpiedSetter<T>.

Test plan

Type test added.

@mrazauskas mrazauskas marked this pull request as draft October 14, 2022 04:52
Comment on lines 142 to 146
const utils = jest.createMockFromModule('../utils');

utils.isAuthorized = jest.fn(secret => secret === 'not wizard');
jest
.spyOn(utils, 'isAuthorized')
.mockImplementation(secret => secret === 'not wizard');
Copy link
Member

Choose a reason for hiding this comment

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

it doesn't make sense to spyOn here - isAuthorized is already a mock function (that's what createMockFromModule does)

Copy link
Contributor Author

@mrazauskas mrazauskas Oct 16, 2022

Choose a reason for hiding this comment

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

Ups.. This change should not be here. My bad (;

Copy link
Member

@SimenB SimenB Oct 16, 2022

Choose a reason for hiding this comment

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

instead of utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); it should probably be utils.isAuthorized.mockImplementation(secret => secret === 'not wizard');

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These lines got autocorrected, because I was playing with jest/prefer-spy-on ESLint rule. I was hoping to find better example for docs, but nothing came out. jest/prefer-spy-on rule will come in later as separate PR (;

@mrazauskas mrazauskas marked this pull request as ready for review October 16, 2022 11:03
@mrazauskas mrazauskas marked this pull request as draft October 16, 2022 11:15
@mrazauskas mrazauskas marked this pull request as ready for review October 16, 2022 11:55

Constructs the type of a spied class or function (i.e. the return type of `jest.spyOn()`).

```ts title="__utils__/setDateNow.ts"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now I am happy about the example. The point was to show that typings can be useful in some test util.

Copy link
Member

@SimenB SimenB left a comment

Choose a reason for hiding this comment

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

nice!

docs/JestObjectAPI.md Outdated Show resolved Hide resolved
/**
* Constructs the type of a spied class or function.
*/
export type Spied<T extends ClassLike | FunctionLike> = JestSpied<T>;
Copy link
Member

Choose a reason for hiding this comment

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

this is copied manually, right? Should we set up a script which keeps it in sync with @jest/globals?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would be possible, but is it worth it? I mean, these types are only used in Jest repo. If something will be missing, typechecks of tests will catch it for us.

Perhaps some check that these types are still exposed in @jest/globals? Just another type test? Sound simple to do and to run automatically. Together with typechecks of test files that should be enough. I will do this as separate PR. If that’s fine? (;

Copy link
Member

Choose a reason for hiding this comment

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

Definitely separate 👍

Co-authored-by: Simen Bekkhus <sbekkhus91@gmail.com>
@SimenB SimenB merged commit faef42e into jestjs:main Oct 16, 2022
@mrazauskas mrazauskas deleted the feat-add-jest.Spied-type-utils branch October 16, 2022 14:14
@SimenB
Copy link
Member

SimenB commented Oct 18, 2022

@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants