vue pinia函数在运行单位测试时未定义。
我有一个组件和一个PINIA商店,其中包含一个状态和一些动作。该代码在浏览器和E2E(柏树)测试中的工作状态非常好,但在单位测试中失败。我正在使用Vue测试效果和vitest。
单击按钮时,可以从单元测试中调用商店功能,但是如果该函数在已安装或主脚本中,则会使测试失败
src/components/userscomponent.vue.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()
(或类似的位置)中拥有存储功能而不会破坏我所有单位测试。
I have a component and a Pinia store which contains a state and some actions. The code works perfectly fine in browser and in E2E (cypress) tests, but fail on unit tests. I'm using vue-testing-utils and vitest.
The store function can be called fine from the unit test when the button is clicked, but if the function is in the mounted or main script, it fails the test
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/tests/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()
})
})
The unit tests return 2 different error. The first is a console log when the function tries to run in onMounted()
and the second is what vitest returns.
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>
I know this example is a little basic and doesn't really serve a purpose, but I'm wondering how I can have store functions inside the onMounted()
(or similar places) without it breaking all my unit tests.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许这对你有用:
Maybe this can be useful to you:
我使用vitest,pinia和测试图(基于VUE检验)。
恕我直言,没有必要:
要模拟onmounted:您的目标不是要检查on已登机称为=&gt;这是VUE内部测试
const userStore = useUserStore();
期望(usersstore.resetstatus).tohavebeencalledtimes(1);
我为所有BebeforeMount做到这一点,并在商店打电话给HTTP调用
,在测试中,
我认为这应该以相同的方式与Vue-Test-Utils一起使用。
我所有组件的钩子都是异步和回归承诺。
I use vitest, pinia and testing-library (based on vue-test-utils).
IMHO, there is no need :
to mock onMounted : you're goal is not to check that onMounted is called => this is Vue internal test
to use vi.spyOn, by default, pinia mocks all methods. You could directly do this in your test :
const usersStore = useUsersStore();
expect(usersStore.resetStatus).toHaveBeenCalledTimes(1);
I do this for all onBeforeMount, onMounted that calls http calls from the store
And in the test
I think this should work with vue-test-utils in the same way.
All my component's hooks are async and return promise.