【问题标题】:vue-test-util click trigger on button not firingvue-test-util单击按钮未触发
【发布时间】:2019-04-26 05:25:58
【问题描述】:

我有一个带有按钮的 Vue 组件。单击按钮时,将调用一个方法。我正在使用 Jest 进行单元测试。我希望vue-test-utils 中的.trigger 方法在按钮上创建一个合成事件,但它什么也没做。

我尝试通过调用wrapper.vm.addService() 直接在包装器上调用该方法,然后使用console.log(wrapper.emitted()),我确实可以看到一个事件已被触发。所以我的问题是为什么addServiceBtn.trigger('click') 什么都不做。

console.log(wrapper.emitted()) 是一个空对象。测试结果失败,错误信息:Expected spy to have been called, but it was not called.

ServiceItem.vue

<template>
  <v-flex xs2>
    <v-card>
      <v-card-text id="itemTitle">{{ item.title }}</v-card-text>
      <v-card-actions>
        <v-btn flat color="green" id="addServiceBtn" @click="this.addService">Add</v-btn>
      </v-card-actions>
    </v-card>
  </v-flex>
</template>

<script>
export default {
  data: () => ({
    title: ''
  }),
  props: {
    item: Object
  },
  methods: {
    addService: function (event) {
      console.log('service item')
      this.$emit('add-service')
    }
  }
}
</script>

tests.spec.js

import { shallowMount, mount } from '@vue/test-utils'
import ServiceItem from '@/components/ServiceItem.vue'
import Vue from 'vue';
import Vuetify from 'vuetify';

Vue.use(Vuetify);

describe('ServiceItem.vue', () => {
  it('emits add-service when Add button is clicked', () => {
    const item = {
      title: 'Service'
    }

    const wrapper = mount(ServiceItem, {
      propsData: { item }
    })

    expect(wrapper.find('#addServiceBtn').exists()).toBe(true)
    const addServiceBtn = wrapper.find('#addServiceBtn')

    const spy = spyOn(wrapper.vm, 'addService')

    console.log(wrapper.emitted())
    addServiceBtn.trigger('click')
    expect(wrapper.vm.addService).toBeCalled()

  })
})

【问题讨论】:

  • 测试expect(wrapper.vm.addService).toBeCalled() 有效吗?

标签: javascript vue.js jestjs vuetify.js vue-test-utils


【解决方案1】:

您的 HTML 代码有一点错误。您将@click 事件绑定到您的方法,而不使用任何this。成功:

 <v-btn flat color="green" id="addServiceBtn" @click="addService($event)">Add</v-btn>

【讨论】:

  • 谢谢!您愿意解释一下为什么this.addService 不起作用吗?
  • @PayamMesgari 因为在 vue 模板中所有的属性和变量都隐式使用 this,所以当你绑定类似这样的东西时不需要添加那里 @click="method" vue 将此模板转换为on: { click: _vm.controlChanged } 在这种情况下 _vm 是这个
【解决方案2】:

其实原代码中的测试不起作用还有另一个原因:函数调用中的括号。 我发现语法 @click="addService" 会导致测试失败,而非常相似(并且在某种程度上不鼓励)的语法 @click="addService()" 会成功。

例子:

test('Click calls the right function', () => {
    // wrapper is declared before this test and initialized inside the beforeEach
    wrapper.vm.testFunction = jest.fn();
    const $btnDiscard = wrapper.find('.btn-discard');
    $btnDiscard.trigger('click');
    expect(wrapper.vm.testFunction).toHaveBeenCalled();
});

使用以下语法此测试失败:

<button class="btn blue-empty-btn btn-discard" @click="testFunction">
  {{ sysDizVal('remove') }}
</button>

但使用以下语法:

<button class="btn blue-empty-btn btn-discard" @click="testFunction()">
  {{ sysDizVal('remove') }}
</button>

【讨论】:

  • 其实在调查了这个问题之后我已经发布了一个类似的问题,并且在接受的答案中你可以找到一些关于如何在不添加括号stackoverflow.com/questions/62696939/… 的情况下进行测试的解释
【解决方案3】:

它不起作用的原因是因为 this.addService in &lt;template&gt; 建议您删除 this 并只说 @click="addService($event)"@click="addService" 也可以正常工作,但没有传入任何事件

【讨论】:

    【解决方案4】:

    对我来说它不起作用,但在使用 vue-test-utils 进行测试时未能触发事件,直到我添加了 .native

    <v-btn @click.native="addToCart($event)">
          Add
    </v-btn>
    
    

    【讨论】:

      猜你喜欢
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-21
      • 2013-01-17
      • 2020-03-26
      相关资源
      最近更新 更多