Vue Test Utils +第三方组件:无法检测到输入事件

时间:2019-07-06 13:49:10

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

我遇到一个问题,只能在测试时使用第三方组件来检测input事件的发出,在浏览器上测试时,组件的行为与预期的一样。使用Vue扩展,我还可以看到它正确地发出了事件。

我使用Choices作为自定义选择。

Vue.component('choices', {
  props: ['options', 'value'],
  template: '#choices-template',
  mounted: function() {
    this.choicesInstance = new Choices(this.$refs.select);
    this.$refs.select.addEventListener('addItem', this.handleSelectChange);
    this.setChoices();
  },
  methods: {
    handleSelectChange(e) {
      this.$emit('input', e.target.value);
    },
    setChoices() {
      this.choicesInstance.setChoices(this.options, 'id', 'text', true);
    }
  },
  watch: {
    value: function(value) {
      console.log('input triggered: ' + value);
    },
    options: function(options) {
      // update options
      this.setChoices();
    }
  },
  destroyed: function() {
    this.choicesInstance.destroy();
  }
})

var vm = new Vue({
  el: '#el',
  template: '#demo-template',
  data: {
    selected: 2,
    options: [{
        id: 1,
        text: 'Hello'
      },
      {
        id: 2,
        text: 'World'
      }
    ]
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css" />

<div id="el"></div>

<!-- using string template here to work around HTML <option> placement restriction -->
<script type="text/x-template" id="demo-template">
  <div>
    <p>Selected: {{ selected }}</p>
    <choices :options="options" v-model="selected">
      <option disabled value="0">Select one</option>
    </choices>
  </div>
</script>

<script type="text/x-template" id="choices-template">
  <select ref="select">
    <slot></slot>
  </select>
</script>

我的测试文件是这样的(我正在使用Jest):

import CustomSelect from '@/CustomSelect';
import { mount } from '@vue/test-utils';

let wrapper,
  options = [
    {
      key: 'Foo',
      value: 'foo',
    },
    {
      key: 'Bar',
      value: 'bar',
    },
    {
      key: 'Baz',
      value: 'baz',
    },
  ];

beforeEach(() => {
  wrapper = mount(CustomSelect, {
    propsData: {
      options,
    },
  });
});

it('Emits an `input` event when selection changes', () => {
  wrapper.vm.choicesInstance.setChoiceByValue([options[1].value]);
  expect(wrapper.emitted().input).not.toBeFalsy();
});
  • wrapper.emitted()在此测试中始终是空对象;
  • 如果我将choicesInstance从我的组件暴露给全局上下文并手动调用choicesInstance.setChoiceByValue('1'),它将正确发出input事件。

0 个答案:

没有答案