Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як тестувати асинхронну поведінку компонента: nextTick і flushPromises?

Vue оновлює DOM асинхронно: зміна стану ставить оновлення в чергу, і DOM змінюється в наступному «тіку». Тест, що перевіряє DOM одразу після зміни, бачить старий стан.

Два різні види очікування:

1. Оновлення DOM після зміни стану - await nextTick() або await на методах Test Utils:

await wrapper.get('button').trigger('click')   // trigger повертає nextTick
expect(wrapper.text()).toContain('Відкрито')

wrapper.vm.open = true                          // пряма зміна стану
await nextTick()

trigger, setValue, setProps уже повертають Promise, що завершується після оновлення DOM - окремий nextTick після них не потрібен.

2. Завершення інших Promise (запити, таймери з Promise, асинхронні дії сторів) - flushPromises():

import { flushPromises, mount } from '@vue/test-utils'

vi.spyOn(api, 'fetchOrders').mockResolvedValue([{ id: 1, total: 100 }])

const wrapper = mount(OrdersList)
await flushPromises()               // дочекатися всіх розв'язаних Promise і рендеру

expect(wrapper.findAll('[data-test="order"]')).toHaveLength(1)

flushPromises чекає, поки виконаються всі вже розв'язані Promise в черзі, - зокрема ланцюжки await усередині компонента після замоканого запиту.

Таймери (setTimeout, debounce) - фальшивий час Vitest:

vi.useFakeTimers()
await wrapper.get('input').setValue('lar')
vi.advanceTimersByTime(300)          // «промотати» debounce
await flushPromises()
vi.useRealTimers()

Асинхронний setup (top-level await у <script setup>) вимагає <Suspense> - у тесті компонент обгортають у Suspense-обгортку і чекають flushPromises().

Типові помилки:

  • тест «зелений» без очікувань: перевірка відбувається до завершення запиту, але випадково збігається з початковим станом (наприклад, «список порожній»);
  • flushPromises замість мокування: справжній мережевий запит він не дочекається - запити в тестах мають бути замокані;
  • реальні таймери роблять тест повільним і нестабільним - фальшиві таймери надійніші.

Докладніше в документації: Vue Test Utils: асинхронна поведінка

Схожі питання