Throughout Vue unit tests, we have taken the habit of using await wrapper.vm.$nextTick()
for every situation where there is some reaction to an event or when dealing with asynchronous code. Most of the time, there is a shorter way to wait for side-effects to be applied:
- When simulating a click, we should instead
await wrapper.trigger("click");
. It waits for Vue to update the DOM in reaction to the click
- When setting some data on a component, we should instead
await wrapper.setData();
. Same, it waits for Vue to update the DOM
- When setting props, we should
await wrapper.setProps();
. It also waits for Vue to update the DOM
- When dealing with promises and asynchronous code, we should use
await jest.runOnlyPendingTimersAsync();
or await vi.runOnlyPendingTimersAsync();
. Previously, we would repeat the $nextTick()
waiting for layered promises (for example, wait for fetch
and then wait for decoding the error Response json). It was not clear how many ticks we had to wait for, leading to confusion.
- When simulating a sub-component event, we should still use
await wrapper.vm.$nextTick()
. There is no built-in method in @vue/test-utils
to await.
- When we want to assert some loading state is shown, we must still use
await wrapper.vm.$nextTick()
. If we wait for the promise to be resolved, our test will never see the loading state.