我正在Vue中使用Jest和Element ui对一个包含带2个选项的select的组件进行单元测试。我从下拉列表中选择一个选项,然后检查是否调用了操作。
1(对于普通的select
和option
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()
})
然而,我使用元素ui的el-select
和el-option
,它们有自己与DOM的交互。
2(使用el-select
和el-option
//Fruit.vue
保持不变,只是select
被el-select
取代,option
被el-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(根据vue-test-utils文档,假设setSelected
实际上是一个别名,我尝试了这种方式:
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(,可以用它来模拟元素ui的el-select
。
在<el-dropdown>
或<el-select>
中触发点击并显示下拉项确实很困难。然后我试着嘲笑所有这些元素。它对我来说很好。
/mock/div.vue
<template>
<div>
<slot></slot>
<slot name="dropdown"></slot>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
inheritAttrs: true
})
</script>
jest.setup.js
import { config } from '@vue/test-utils'
import Div from './mock/div.vue'
config.global.components = {
ElDropdown: Div,
ElDropdownItem: Div,
ElDropdownMenu: Div
}
我可以通过点击您想要模拟的下拉项来实现这一点:
wrapper.findAll('.el-select-dropdown__item').at(1).trigger('click');
await Vue.nextTick();
expect(YourExpectStatement);
Vue.nextTick((对我来说是必要的,因为它允许DOM更新它的周期,更多信息请点击这里。还要注意,您需要使测试功能异步,例如:
it('Async test name', async () => {