suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Die Funktion von Vue Pinia ist in onMounted beim Ausführen von Komponententests nicht definiert

Ich habe eine Komponente und einen Pinia-Store, der den Status und einige Operationen enthält. Der Code läuft in Browser- und E2E-Tests (Cypress) einwandfrei, schlägt jedoch in Unit-Tests fehl. Ich verwende vue-testing-utils und vitest.

Der Aufruf einer gespeicherten Funktion aus dem Komponententest funktioniert einwandfrei, wenn auf die Schaltfläche geklickt wird. Wenn sich die Funktion jedoch im installierten oder Hauptskript befindet, schlägt der Test fehl

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()
  })
})

Unit-Test gibt 2 verschiedene Fehler zurück. Das erste ist das Konsolenprotokoll, wenn die Funktion ausgeführt werden soll onMounted() und das zweite ist das, was vitest zurückgibt.

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>

Ich weiß, dass dieses Beispiel etwas einfach ist und nicht wirklich seinen Zweck erfüllt, aber ich würde gerne wissen, wie ich Funktionen in onMounted() (oder an einem ähnlichen Ort) speichern kann, ohne alle meine Komponententests zu zerstören.

P粉103739566P粉103739566388 Tage vor772

Antworte allen(1)Ich werde antworten

  • P粉451614834

    P粉4516148342023-11-01 14:56:54

    也许这对您有用:

    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)
      })
    })

    Antwort
    0
  • StornierenAntwort