Sinon如何监视由Vue事件触发的Vue组件方法?

awh*_*who 3 sinon vuejs2

为了描述我的问题而进行的基本设置:

使用vue-cli 2.8.2,我基于webpack模板(vue init webpack vue-test-sinon-spy)生成了一个新项目,其中保留了vue-cli的所有默认值(禁用eslint无关)。

在此vue-cli生成的项目中所做的更改:

  1. 我在Hello.vue的h2标签上附加了一个事件:
<h2 @click="sayHello">Essential Links</h2>
Run Code Online (Sandbox Code Playgroud)
  1. 我在Hello组件中添加了一个方法
<script>
export default {
  ...
  methods: {
    sayHello() {
      console.log('hello!')
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)
  1. 我在Hello.spec.js中添加了一个新测试
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)
  })
})
Run Code Online (Sandbox Code Playgroud)

当我以编程方式单击html标记(使用vm.$el.querySelector('h2').click())时,间谍不会捕获该方法的执行sayHello,因此vm.sayHello.callCount将为0。不是我所喜欢的。

但是,如果我直接调用sayHello(使用vm.sayHello()),vm.sayHello.callCount则将为1。

如果我想模拟html标签()的点击,而不直接调用(no ),如何让间谍捕获的调用sayHello(因此vm.sayHello.callCount将为1 )?vm.$el.querySelector('h2').click()sayHellovm.sayHello()

谢谢

bri*_*anf 6

这里的问题是,在安装组件时,回调函数已绑定到事件。我不确定它在后台如何工作,但是就像它sayHello在click事件作用域内的方法的副本一样。绑定后便无法修改。

之后,您将在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)
    ...
})
Run Code Online (Sandbox Code Playgroud)