Компонент:
<template>
<div>
<p v-if="loading">Загрузка...</p>
<p v-else>{{ data }}</p>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const data = ref('');
const loading = ref(true);
const fetchData = async () => {
// Имитация загрузки
await new Promise(resolve => setTimeout(resolve, 100));
data.value = 'Данные загружены';
loading.value = false;
};
onMounted(() => {
fetchData();
});
</script>
Задание:
Проверьте, что сначала отображается "Загрузка...", а после завершения fetchData — "Данные загружены".
Для того чтобы управлять таймерами в vitest есть:
vi.runAllTimers() - Этот метод выполняет все запланированные макросы (макротаски), которые включают:
Рекурсивные/вложенные таймеры
setTimeout()
setInterval()
setImmediate() (в Node.js)
Использование:
import { vi } from 'vitest'
// Включаем моки таймеров
vi.useFakeTimers()
// Запускаем все таймеры
vi.runAllTimers()
Так же, при тестировании компонентов с промисами, необходимо дождаться их выполнения:
await Promise.resolve();
await wrapper.vm.$nextTick();
Решение:
import { mount } from '@vue/test-utils';
import { vi, it, describe } from 'vitest';
import Async from '@/components/Async.vue';
describe('Async.vue', () => {
it('отображает загрузку, затем данные', async () => {
vi.useFakeTimers();
const wrapper = mount(Async);
expect(wrapper.find('p').text()).toBe('Загрузка...');
vi.runAllTimers(); // выполняем все таймеры
await Promise.resolve(); // выполняем промис, без этого сам таймер выполнится а вот промис нет
await wrapper.vm.$nextTick(); // обновление DOM
expect(wrapper.find('p').text()).toBe('Данные загружены');
vi.useRealTimers();
})
})