我正在使用复合API和vue3钩子运行一个setup()应用程序。
我使用Vitest作为单元测试框架。(v0.6.1)
我有以下示例组件:
// src/components/MyComponent.vue
<template>
<div>
<h1>counter : {{ counter }}</h1>
<button
@click="incrementCounter"
>
Click
</button>
</div>
</template>
<script setup lang="ts">
// imports
import { ref } from 'vue'
// datas
const counter = ref(1)
// methods
const incrementCounter = () => {
if (confirm()) { // call the confirm method
counter.value++ // increment counter by 1
}
}
const confirm = () => {
return true
}
</script>以及它的测试文件:
// src/components/MyComponent.spec.ts
import {
shallowMount
} from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
describe('component/MyComponent.vue', () => {
it('incrementCounter method', () => {
const wrapper = shallowMount(MyComponent) // create the wrapper
const confirmSpy = vi.spyOn(wrapper.vm, 'confirm') // create the confirm method spy
wrapper.vm.incrementCounter() // use the incrementCounter method
expect(wrapper.vm.counter).toBe(2) // test passed
expect(confirmSpy).toHaveBeenCalled() // test failed
})
})测试的目的仅仅是验证confirm()方法是否在incrementCounter()方法中被调用。
我试图在被封()方法的间谍中使用最重要的confirm()方法,但最终测试失败了,收到了以下消息:
重新进行测试..。src/components/MyComponent.spec.ts 组件/MyComponent.spec.ts>Component.vue> incrementCounter方法→期望至少调用一次 ⎯⎯⎯⎯⎯⎯⎯失败测试1⎯⎯⎯⎯⎯⎯⎯ 失败src/components/MyComponent.spec.ts >Component.vue incrementCounter方法AssertionError:预期的“确认”至少会被调用一次:❯src/Component.spec.ts:13:23 11 wrapper.vm.incrementCounter() //使用incrementCounter方法12 x expect(wrapper.vm.counter).toBe(2) /测试通过了13欧元期望值(ConfirmSpy).toHaveBeenCalled()/测试失败了吗?
这似乎表明confirm()方法没有被调用,但是由于计数器值已经增加到2,我猜这意味着实际上已经有效地调用了该方法。
我用spyOn()方法错了吗?我该怎么做才能通过这次考试?
提前谢谢你的帮助。
发布于 2022-05-09 03:55:12
在这种情况下,不能对confirm在incrementCounter()中的引用进行外部修改。这就像修改函数的私有变量一样不可能。
下面是一个类似的普通JavaScript示例,它演示了<script setup>中的代码正在尝试什么(运行下面的演示代码片段):
function setup() {
const incrementCounter = () => {
confirm()
}
const confirm = () => {
console.log('confirm')
}
return {
incrementCounter,
confirm,
}
}
const comp = setup()
comp.incrementCounter()
console.log('trying to update confirm...')
comp.confirm = () => console.log('Yes do it!')
comp.incrementCounter() // ❌ still calls original confirm
但是,对象的属性可以从外部修改。因此,解决方法是通过一个对象将incrementCounter()更新为引用confirm,稍后我们将更新该对象:
function setup() {
const incrementCounter = () => {
/**/
ctx.confirm()
}
const confirm = () => {
console.log('confirm')
}
/**/
const ctx = {
incrementCounter,
confirm,
} /**/
return ctx
}
const comp = setup()
comp.incrementCounter()
console.log('trying to update confirm...')
comp.confirm = () => console.log('Yes do it!')
comp.incrementCounter() // ✅ calls new confirm above
使用同样的技术,incrementCounter()可以通过<script setup>中的一个对象引用confirm
<!-- MyComponent.vue -->
<script setup>
import { ref } from 'vue'
const counter = ref(1)
const incrementCounter = () => {
/**/
if (ctx.confirm()) {
// call the confirm method
counter.value++ // increment counter by 1
}
}
const confirm = () => {
return true
}
/**/
const ctx = {
confirm
}
</script>现在,您可以在spyOn上使用ctx.confirm。
// MyComponent.spec.js
import { describe, it, expect, vi } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
describe('component/MyComponent.vue', () => {
it('incrementCounter method', () => {
const wrapper = shallowMount(MyComponent)
/**/
const confirmSpy = vi.spyOn(wrapper.vm.ctx, 'confirm')
wrapper.vm.incrementCounter()
expect(wrapper.vm.counter).toBe(2)
expect(confirmSpy).toHaveBeenCalled() /*✅*/
})
})https://stackoverflow.com/questions/72084274
复制相似问题