我有一个组件和一个 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) }) })