使用 element-ui 和 vue-test-utils 模拟选择

Posted

技术标签:

【中文标题】使用 element-ui 和 vue-test-utils 模拟选择【英文标题】:Simulate select with element-ui and vue-test-utils 【发布时间】:2019-05-13 22:30:54 【问题描述】:

我正在使用 Vue 中的 Jest 和 Element-ui 对包含带有 2 个选项的选择的组件进行单元测试。我正在从下拉列表中选择一个选项,然后检查是否调用了某个操作。

1) 使用普通的selectoption html 标签可以完美运行。

// Fruit.vue

<template lang="pug">
  select(
    v-model="fruit"
  )
    option(
      v-for="item in fruits"
      :label="item.label"
      :value="item.value"
    )
</template>
<script>
export default 
  data () 
    return 
      fruits: [
        
          label: 'Banana',
          value: false
        ,
        
          label: 'Apple',
          value: false
        
      ]
    
  ,
  computed: 
    fruit: 
      get () 
        return this.$store.state.fruit
      ,
      set (fruit) 
        this.$store.dispatch('setSelectedFruit',  fruit )
      
    
  
</script>

// DOM

<select>
  <option label="Banana" value="false"></option>
  <option label="Apple" value="false"></option>
</select>

// Fruit.spec.js

it('calls the "setSelectedFruit" action when a value is selected', () => 
  const wrapper = mount(Fruit,  store, localVue )
  const options = wrapper.find('select').findAll('option')


  options.at(1).setSelected()
  expect(actions.setSelectedFruit).toHaveBeenCalled()
)

但是我使用 element-ui 的 el-selectel-option,它们与 DOM 有自己的交互。

2) 使用el-selectel-option

// Fruit.vue

保持不变,只是 selectel-select 替换,optionel-option 替换。

// DOM

<div class="el-select-dropdown">
  <div class="el-select-dropdown__wrap">
    <ul class="el-select-dropdown__list">
      <li class="el-select-dropdown__item">
        <span>Banana</span>
      </li>
      <li class="el-select-dropdown__item">
        <span>Apple</span>
      </li>
    </ul>
  </div>
</div>

// Fruit.spec.js

a)

it('calls the "setSelectedFruit" action', () => 
  const wrapper = mount(Fruit,  store, localVue )
  const options = wrapper.find('.el-select-dropdown__list').findAll('el-select-dropdown__items')

  options.at(1).setSelected()
  expect(actions.setSelectedFruit).toHaveBeenCalled()
)

b)鉴于setSelected实际上是根据vue-test-utils documentation的别名,我这样尝试:

it('calls the "setSelectedFruit" action', () => 
  const wrapper = mount(Fruit,  store, localVue )
  const options = wrapper.findAll('.el-select-dropdown__item')
  const select = wrapper.find('.el-select-dropdown__list')

  options.at(1).element.selected = false
  select.trigger('change')
  expect(actions.setSelectedFruit).toHaveBeenCalled()
)

使用第二种方法,选择的option 设置为selected,但select 上的触发器不起作用,因此v-model 没有更新。

所以我想知道是否有人对此有解决方案,或者是否有另一个库(vue-test-utils 除外)可以模拟 element-ui 的 el-select >.

【问题讨论】:

你试过用select.vm.$emit('change', 1)代替trigger吗? (1 是所选元素的值)或$emit('input', 1) ? 【参考方案1】:

我可以通过点击您想要模拟的下拉项目来完成这项工作:

wrapper.findAll('.el-select-dropdown__item').at(1).trigger('click');
await Vue.nextTick();
expect(YourExpectStatement);

我需要 Vue.nextTick(),因为它允许 DOM 更新它的循环,更多 info here。另请注意,您需要使测试函数异步,例如:

it('Async test name', async () => 

【讨论】:

以上是关于使用 element-ui 和 vue-test-utils 模拟选择的主要内容,如果未能解决你的问题,请参考以下文章

vue中的element-ui和react的element-ui

element-ui需要打开服务器

使用 element-ui 和 vue-test-utils 模拟选择

VUE的element-ui的使用

使用vuejs2.0和element-ui 搭建的一个后台管理界面

使用vuejs2.0和element-ui 搭建的一个后台管理界面