我为描述问题所做的基本设置:
使用vue-cli 2.8.2,我基于webpack模板(vue init webpack vue-test-sinon-spy
)生成了一个新项目,保留了vue-cli的所有默认值(除了禁用eslint之外的无关例外)。
在此vue-cli生成的项目中完成的更改:
<h2 @click="sayHello">Essential Links</h2>
<script>
export default {
...
methods: {
sayHello() {
console.log('hello!')
}
}
}
</script>
describe('Hello.vue', () => {
// ...
it('should handle click on h2 tag', () => {
const Constructor = Vue.extend(Hello)
const vm = new Constructor().$mount()
sinon.spy(vm, 'sayHello')
// [A] if I run the line below, vm.sayHello.callCount will be 0 - not as expected
vm.$el.querySelector('h2').click()
// [B] if I run the line below, vm.sayHello.callCount will be 1 - as expected
// vm.sayHello()
// vm.sayHello.callCount will be 0 or 1, depending on
// what line I execute ([A] or [B]),
// even if in both cases sayHello method is really executed
console.log('###', vm.sayHello.callCount)
})
})
当我以编程方式单击html标记(使用vm.$el.querySelector('h2').click()
)时,间谍不会捕获方法sayHello
的执行,因此vm.sayHello.callCount
将为0.不是我的意思等。
但是,如果我直接致电sayHello
(使用vm.sayHello()
),vm.sayHello.callCount
将为1.正如我所料。
如果我想模拟html标记(sayHello
)上的点击,我如何让间谍捕获vm.sayHello.callCount
的调用(以便vm.$el.querySelector('h2').click()
为1),以及没有直接致电sayHello
(没有vm.sayHello()
)?
由于
答案 0 :(得分:5)
这里的问题是当组件被挂载时,回调被绑定到事件。我不确定它在后台是如何工作的,但它就像是click事件范围内sayHello
方法的副本。在绑定后你无法对其进行修改。
您正在使用components方法创建间谍。他们的行为相同,但事实并非如此。一个是间谍,一个不是。
wrapper.vm.sayHello()
执行方法(侦察)
wrapper.find('h2').trigger('click')
执行回调(未监视)
在安装之前在组件类上创建间谍而不是之后的实例,它应该按预期工作。
it('should handle click on h2 tag - vue-test-utils + dummy click version', () => {
const clickSpy = sinon.spy(Hello.methods, 'sayHello')
const wrapper = mount(Hello)
...
})
答案 1 :(得分:0)
(注意Phil's comment这不是单位测试的有效用法。)
我找到的解决方法是:
安装vue-test-utils:yarn add --dev https://github.com/vuejs/vue-test-utils
(afaiu,vue-test-utils还是not officially released)
触发虚拟点击事件
现在,您可以添加一个新测试,该测试将按预期运行:
describe('Hello.vue', () => {
// ...
it('should handle click on h2 tag - vue-test-utils + dummy click version', () => {
const wrapper = mount(Hello)
sinon.spy(wrapper.vm, 'sayHello')
// trigger a dummy click event
wrapper.find('h1').trigger('click')
// [A] if I run the line below, vm.sayHello.callCount will be 1 - as expected
wrapper.find('h2').trigger('click')
// [B] if I run the line below, vm.sayHello.callCount will be 1 - as expected
// wrapper.vm.sayHello()
// vm.sayHello.callCount will be 1 in both [A] and [B] cases
console.log('#####', wrapper.vm.sayHello.callCount)
})
})
这种行为太奇怪了,让Vue看起来更像是一个宠物项目而不是2.x.x项目,也许我误解了一些东西。