J'ai un composant et un magasin Pinia qui contiennent l'état et certaines opérations. Le code fonctionne parfaitement dans les tests de navigateur et E2E (cyprès), mais échoue dans les tests unitaires. J'utilise vue-testing-utils et vitest.
L'appel d'une fonction stockée à partir d'un test unitaire fonctionne correctement lorsque le bouton est cliqué, mais si la fonction est installée ou dans le script principal, le test échoue
src/components/UsersComponent.vue
<script setup> import { onMounted } from 'vue' import { useUsersStore } from '@/stores/users.store' const usersStore = useUsersStore() // usersStore.resetStatus() // <- This fails in the unit test onMounted(() => { usersStore.resetStatus() // <- This fails in the unit test }) function changeStatus() { usersStore.changeStatus() // <- This passes in the unit test } </script> <template> <div> <p>Status: {{ usersStore.status }}</p> <button @click="changeStatus()">Change Status</button> </div> </template>
src/stores/users.store.js
import { defineStore } from 'pinia' import { usersAPI } from '@/gateways' export const useUsersStore = defineStore({ id: 'users', persist: true, state: () => ({ status: 'ready', }), getters: {}, actions: { resetStatus() { this.status = 'ready' }, changeStatus() { this.status = 'loading' }, }, })
src/components/test/UsersComponent.spec.js
import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount } from '@vue/test-utils' import { createTestingPinia } from '@pinia/testing' import UsersComponent from '@/components/UsersComponent.vue' import { useUsersStore } from '@/stores/users.store' const wrapper = mount(UsersComponent, { global: { plugins: [createTestingPinia({ createSpy: vi.fn() })], }, }) const usersStore = useUsersStore() describe('UsersComponent', () => { it('store function is called', async () => { // arrange const spy = vi.spyOn(usersStore, 'resetStatus') const button = wrapper.find('button') // act await button.trigger('click') // assert expect(spy).toHaveBeenCalled() }) })
Le test unitaire renvoie 2 erreurs différentes. Le premier est le journal de la console lorsque la fonction tente de s'exécuter dans onMounted()
et le second est ce que renvoie Vitest.
stderr | unknown test [Vue warn]: Unhandled error during execution of mounted hook at <UsersComponent ref="VTU_COMPONENT" > at <VTUROOT>
FAIL src/components/__tests__/UsersComponent.spec.js [ src/components/__tests__/UsersComponent.spec.js ] TypeError: usersStore.resetStatus is not a function ❯ src/components/UsersComponent.vue:16:14 16| 17| <template> 18| <div> | ^ 19| <p>Status: {{ usersStore.status }}</p> 20| <button @click="changeStatus()">Change Status</button>
Je sais que cet exemple est un peu basique et ne sert pas vraiment à l'objectif, mais j'aimerais savoir comment stocker des fonctions dans onMounted()
(ou quelque part similaire) sans casser tous mes tests unitaires.
Peut-être que cela vous sera utile :