Tester les composants asynchrones
Utilisation de flushPromises
Lors du test de composants qui effectuent des opérations asynchrones, vous aurez besoin d’attendre que ces opérations se terminent avant de vérifier les résultats. @vue/test-utils
fournit une fonction utilitaire flushPromises
qui attend que toutes les promesses en attente soient résolues.
import { mount } from '@vue/test-utils'import { flushPromises } from '@vue/test-utils'import { describe, it, expect, vi } from 'vitest'import UserProfile from '@/components/UserProfile.vue'import { fetchUserData } from '@/api/user'
// Mock le module d'APIvi.mock('@/api/user', () => ({ fetchUserData: vi.fn()}))
describe('UserProfile.vue', () => { it('loads and displays user data', async () => { // Préparer le mock avec les données fetchUserData.mockResolvedValue(userData)
const wrapper = mount(UserProfile)
// Initialement, devrait afficher un loader expect(wrapper.find('.loading').exists()).toBe(true) expect(wrapper.find('.user-info').exists()).toBe(false)
// Attendre que toutes les promesses soient résolues await flushPromises()
// Maintenant le loader devrait être caché et les infos utilisateur affichées expect(wrapper.find('.loading').exists()).toBe(false) expect(wrapper.find('.user-info').exists()).toBe(true) expect(wrapper.text()).toContain('John Doe') })})
Comment fonctionne flushPromises
La fonction flushPromises
est particulièrement utile car elle:
- Attend que toutes les promesses en attente dans la file d’attente des microtâches soient résolues
- Met à jour le DOM après la résolution des promesses
- Permet de tester l’état du composant après une opération asynchrone
C’est une alternative à l’utilisation de setTimeout
qui peut être moins fiable et moins claire.
Tester les erreurs asynchrones
Vous pouvez également tester le comportement de votre composant lorsqu’une opération asynchrone échoue:
it('handles error state when API call fails', async () => { // Configurer le mock pour rejeter la promesse fetchUserData.mockRejectedValue(new Error('API Error'))
const wrapper = mount(UserProfile)
// Attendre que toutes les promesses soient résolues (ou rejetées) await flushPromises()
// Vérifier que le message d'erreur s'affiche expect(wrapper.find('.error-message').exists()).toBe(true) expect(wrapper.text()).toContain('Une erreur est survenue')})
Tester avec Vue Router et navigation asynchrone
Si votre composant utilise Vue Router et effectue des navigations, vous devrez également attendre que ces navigations soient terminées:
import { mount } from '@vue/test-utils'import { flushPromises } from '@vue/test-utils'import { createRouter, createWebHistory } from 'vue-router'import { describe, it, expect } from 'vitest'import NavComponent from '@/components/NavComponent.vue'
// Créer un router de testconst router = createRouter({ history: createWebHistory(), routes: [/* vos routes */]})
it('navigates when button is clicked', async () => { const wrapper = mount(NavComponent, { global: { plugins: [router] } })
// Cliquer sur un bouton qui déclenche une navigation await wrapper.find('button').trigger('click')
// Attendre que la navigation soit terminée await flushPromises()
// Vérifier que la navigation a eu lieu expect(router.currentRoute.value.path).toBe('/expected-path')})