Die Funktion von Vue Pinia ist in onMounted beim Ausführen von Komponententests nicht definiert
P粉103739566
P粉103739566 2023-10-31 21:58:42
0
1
793

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粉103739566
P粉103739566

Antworte allen(1)
P粉451614834

也许这对您有用:

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)
  })
})
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage