The basic setup that I've done in order to describe my problem:
Using vue-cli 2.8.2, I generated a new project based on webpack template (vue init webpack vue-test-sinon-spy
) keeping all the defaults of vue-cli (with the irrelevant exception of disabling eslint).
Changes done in this vue-cli generated project:
<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)
})
})
When I programmatically click the html tag (using vm.$el.querySelector('h2').click()
), spy won't capture the execution of the method sayHello
, thus vm.sayHello.callCount
will be 0. Not what I like.
But, if I directly call sayHello
(using vm.sayHello()
), vm.sayHello.callCount
will be 1. As I expect.
How can I make spy capture the call of sayHello
(so that vm.sayHello.callCount
will be 1), if I want to simulate the click on the html tag (vm.$el.querySelector('h2').click()
), and not directly calling sayHello
(no vm.sayHello()
)?
Thanks
The problem here is that callback is being bound to the event when the component is mounted. I'm not sure exactly how it works in the background but it's like its a copy of the sayHello
method within the click event scope. You can't modify it after it has been bound.
You are creating the spy after that on the components method. They act the same but they are not. One is a spy and one is not.
wrapper.vm.sayHello()
executes the method (spied on)
wrapper.find('h2').trigger('click')
executes the callback (not spied on)
Create the spy on the component Class before mounting rather than the instance afterwards and it should work as expected.
it('should handle click on h2 tag - vue-test-utils + dummy click version', () => {
const clickSpy = sinon.spy(Hello.methods, 'sayHello')
const wrapper = mount(Hello)
...
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With