-
Notifications
You must be signed in to change notification settings - Fork 264
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
Bug: event handlers not invoked when using jest.useFakeTimers
or vi.useFakeTimers
#1854
Comments
Sorry to post this as a bug, when it really isn't a bug in VTU. I spent a considerable amount of time debugging this, and I thought it was likely that others experiencing this issue would look here for answers. Hopefully this is helpful to someone else. |
Another workaround from the linked // won't trigger this issue
vi.useFakeTimers({
toFake: ['setTimeout', 'clearTimeout']
}) // will trigger this issue
vi.useFakeTimers({
toFake: ['setTimeout', 'clearTimeout', 'Date']
}) |
Interesting, thanks @aethr for taking the time to share this issue and the solution you found 👍 I'm wondering what we can do in VTU to help. Maybe |
Describe the bug
We are experiencing an issue in our unit and integration tests that utilise
useFakeTimers
when using:[email protected]
on[email protected]
[email protected]
on[email protected]
Components with event bindings on outer elements are not having their handlers invoked when using
useFakeTimers
in jest or vitest.To Reproduce
https://codesandbox.io/s/vue3-vue-test-utils-vitest-5yex3q?file=/src/useFakeTimers.test.js
Expected behavior
We expect all relevant event handlers to be invoked when
userFakeTimers
is used.Related information:
@vue/test-utils
version: 2.2.1Vue
version: 3.2.40+vitest
version: 0.25.1Related issue in
vitest
: vitest-dev/vitest#649Additional context
This isn't actually a bug in VTU, it's a side-effect of a recent edge-case change to
vue
, visible here: https://github.com/vuejs/core/blob/5ee40532a63e0b792e0c1eccf3cf68546a4e23e9/packages/runtime-dom/src/modules/events.ts#L100-L104Vue is trying to prevent an edge case where an inner event handler causes a state change that attaches new event handlers to outer elements, where the new event handlers would catch the original event as it bubbles outwards. This code won't invoke any event handlers that were attached in the same tick when the event was created.
Using
useFakeTimers
mocks theDate
object, and causes allDate.now()
to return the same value, which means that handlers and events all get the same timestamp, so the check in the code linked above prevents event handlers from firing.A simple workaround is to advance the timers after the component is mounted, but before the event is invoked (see the last unit test in the codesandbox).
I've created a simple plugin that will advance timers by 1ms before triggering any event if
useFakeTimers
is in use:The text was updated successfully, but these errors were encountered: