-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Bug: Spy is not called if you don't add parentheses to the function handler #2066
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
Comments
This is expected behavior. It's impossible to track down a spy, when it looses its parent object. It's not Vue problem, this is how spying on an object works. I would recommend not using this pattern with spies when testing web components. You are testing implementation details instead of actual interactions with DOM. Here is a good read on the subject: https://kentcdodds.com/blog/testing-implementation-details |
I'll have a read, thanks for the recommendation! 👍 |
People at
|
Maybe documenting the behaviour could be a good starting point? |
This is how mocking works in JavaScript. I am not sure what do you want to document? You are applying a mock to an object's method too late - the "onClick" in |
How comes it's already rendered when written without parentheses, and is not already rendered when using parentheses? 🤔 |
Because it's a function call, it's not evaluated yet. |
Then as the |
I guess. It's not up to Vitest how vue generates js 🤷🏻♂️ This code is already evaluated, so when you are spying on const vm = {
fn() {},
template: `<div @click="fn" />`
}
render(vm) // produses, let's say { onClick: vm.fn }
vi.spyOn(vm, 'fn') // template is already evaluated, and pointer is lost basically Here you always have access to it: const vm = {
fn() {},
template: `<div @click="fn()" />`
}
render(vm) // produses, let's say { onClick: () => vm.fn() }
vi.spyOn(vm, 'fn') // function is not evaluated yet, and you will always have access to vm.fn there |
Describe the bug
Right now if you have a child component that handles an emitted event by calling a function in the parent component, it will just fail if you don't add parenthesis to the event handler name.
To Reproduce
This doesn't work:
This works:
I just found out about this unexpected behaviour by chance.
It's weird because in the Vue docs they use the non-parentheses version all over the place.
Expected behavior
This should work:
Related information:
This is with a newly created Vue 3 + Vite + TypeScript application (
pnpm create vite
).Additional context
Here is a simple example:
That's the gist of it.
Alternative Solutions
For now, use parenthesis on all event handlers and manually pass any data to it... :(
Add information about this issue in a very visible place on the Vitest docs (didn't find anything about it when going through the site, it should be a big yellow warning box). :)
Previous discussions
vuejs/test-utils#1769 (most recent one)
vuejs/vue-test-utils#1901
vuejs/vue-test-utils#929
https://stackoverflow.com/questions/62696939/test-on-function-call-in-vue-template-only-passes-if-the-function-is-called-with/62703070#62703070
Reproduction
I have repo with a brand new Vite + Vue 3 app that exhibits the behaviour discussed above right here: https://github.com/lobo-tuerto/test-utils-parentheses
Please clone it, install dependencies (I'm using pnpm), then run:
pnpm vitest run
You'll see:
Please note that this line in
src/App.vue
does not have parentheses in its event handler:Now, add parentheses to it like this:
Run
pnpm vitest run
again and you'll see:That's basically the issue.
Hope this helps troubleshoot what's going on.
Thank you in advance.
System Info
Used Package Manager
pnpm
Validations
The text was updated successfully, but these errors were encountered: