La fonction de Vue Pinia n'est pas définie dans onMounted lors de l'exécution de tests unitaires
P粉103739566
P粉103739566 2023-10-31 21:58:42
0
1
763

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.

P粉103739566
P粉103739566

répondre à tous(1)
P粉451614834

Peut-être que cela vous sera utile :

describe('UsersComponent',  () => {
  it('changeStatus function is called', async () => {
    const wrapper = mount(UsersComponent, {
      mounted: vi.fn(), // With this you mock the onMounted
      global: {
        plugins: [createTestingPinia({
          initialState: { // Initialize the state
            users: { status: 'ready' }, 
          }
        })]
      }
    })  
  
    // Spy the method you call...
    const spy = vi.spyOn(wrapper.vm, 'changeStatus');

    wrapper.vm.changeStatus()

    expect(spy).toHaveBeenCalled()
    expect(spy).toHaveBeenCalledTimes(1)
  })
})
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal