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
Add spyOn function introduced in Jest 19 #14867
Conversation
jest/index.d.ts to authors (@pspeter3 @vsiao @NoHomey @jwbay @asvetliakov). Could you review this PR? Checklist
|
jest/index.d.ts
Outdated
@@ -83,6 +83,8 @@ declare namespace jest { | |||
function useFakeTimers(): typeof jest; | |||
/** Instructs Jest to use the real versions of the standard timer functions. */ | |||
function useRealTimers(): typeof jest; | |||
/** Creates a mock function similar to jest.fn but also tracks calls to object[methodName] */ | |||
function spyOn(object: any, method: string): typeof jest; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest this
function spyOn<T extends {}, M extends keyof T>(object: T, method: M): MockInstance<T[M]>;
Also return type typeof jest
is wrong. jest.spyOn
returns mock/spy instance not the global jest object
Better T extends object
but this require TS 2.2 and PR won't be merged until 4-6 weeks passed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asvetliakov you're right about the return type, my mistake.
About the other thing, I see the benefit so you assure is an existing property of that object. Does that take into account custom properties? Because I assume T extends {}
creates a new Object type.
Anyway, if that'll take that much time, I could always create another PR by that time, but at least if we merge this now spyOn will be usable in ts-jest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T extends {}
infers type from parameter, so it will be your type that you had passed into spyOn. keyof T
will filter properties for this type only.
I've also realized I didn't put it in the right alphabetical order. What about the new change? It's not as good as what @asvetliakov but it will work right now since doesn't need the
|
Why you dislike |
Sorry, got confused. I do like Well, to return Is it ok the following implementation? And will it take long to get merged? function spyOn<T>(object: T, method: string): Mock<T>; If not, then should we go for what you @asvetliakov? function spyOn<T extends {}, M extends keyof T>(object: T, method: M): MockInstance<T[M]>; And, would it matter too much the return type to be Mock or MockInstance? Sorry for these many questions but I'm not a TS expert and is my first PR to this repo 😄 |
@alexjoverm can you please refresh the PR against master. |
@alexjoverm The second option in your last post is definitely preferable. About MockInstance vs Mock, the difference is that Mock has construct and call signatures. If spyOn returned a Mock type, you'd able to do this const spy = jest.spyOn(obj, 'foo');
spy(); //call
new spy(); //construct But I don't know when it makes sense to call your own spy in a test. And if you really wanted to, you could just call the method directly on the object instead. Something this PR is missing though is mockRestore. See the example test here: http://facebook.github.io/jest/docs/jest-object.html#jestspyonobject-methodname. Although it can be called on every mock, it may be confusing since it's a no-op on everything except spies. I would suggest this for spyOn's return type. interface SpyInstance<T> extends MockInstance<T> {
mockRestore(): void;
} |
Ok done. Since hundreds of commits are in between because of the merge, I preferred not to rewrite history, just in case it breaks something for others. |
@jwbay mind taking another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Please fill in this template.
master
branch.tsc
without errors.npm run lint package-name
if atslint.json
is present.If changing an existing definition:
tslint.json
containing{ "extends": "../tslint.json" }
.