我有一個元件和一個 Pinia 存儲,其中包含狀態和一些操作。該程式碼在瀏覽器和 E2E(cypress)測試中運行得非常好,但在單元測試中失敗。我正在使用 vue-testing-utils 和 vitest。
點擊按鈕時,可以從單元測試中很好地呼叫儲存函數,但如果函數位於已安裝或主腳本中,則測試會失敗
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/測試/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() }) })
單元測試傳回 2 個不同的錯誤。第一個是函數嘗試在 onMounted()
中執行時的控制台日誌,第二個是 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>
我知道這個例子有點基本,並沒有真正達到目的,但我想知道如何在onMounted()
(或類似的地方)中擁有存儲函數,而不破壞我的所有單元測試。
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) }) })