如何在 BootstrapVue 元素上使用 Vue Test Utils 触发事件?
How to trigger event with Vue Test Utils on a BootstrapVue element?
这个问题让我很难过,我无法理解如何让 Vue Test Utils 和 BootstrapVue 一起玩得很好。
一个最小的例子是这样的:
MyComponent.vue
<template>
<div>
<b-button variant="primary" @click="play">PLAY</b-button>
</div>
</template>
<script>
export default {
name: 'MyComponent',
methods: {
play() {
console.log("Let's play!");
}
}
}
</script>
在main.js
中我们使用BootstrapVue:Vue.use(BootstrapVue)
.
这就是我尝试测试 click
事件是否已被触发的方式:
import { expect } from 'chai';
import sinon from 'sinon';
import Vue from 'vue';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import BootstrapVue, { BButton } from 'bootstrap-vue';
import MyComponent from '@/components/MyComponent.vue';
const localVue = createLocalVue();
localVue.use(BootstrapVue);
describe('MyComponent.vue', () => {
it('should call the method play when button is clicked', () => {
const playSpy = sinon.spy();
const wrapper = shallowMount(MyComponent, {
localVue,
methods: {
play: playSpy,
},
});
wrapper.find(BButton).trigger('click');
expect(playSpy.called).to.equal(true);
});
});
这给了我:
AssertionError: expected false to equal true
+ expected - actual
-false
+true
我检查了 ,但不适用于 BButton
。
当 运行 测试时,我也没有在命令行上看到任何输出,我希望在其中执行此行:
console.log("Let's play!");
这是怎么回事?
无法触发事件 click
的原因是 shallowMount
与 mount
相比的工作方式。
我们知道,Vue Test Utils 提供了两种方法来挂载组件,即渲染模板和生成 DOM 树:
- 坐骑
- shallowMount
第一种方法mount
生成一棵完整的DOM树,遍历所有子组件。大多数时候这不是必需的,因此首选方法 shallowMount
- 它将子组件存根到父组件的下一级。
就我而言,这也是问题的根源。 BootstrapVue 提供组件,如 BButton
,可以在您自己的 Vue 模板中使用。这意味着在以下模板中:
<template>
<div>
<b-button variant="primary" @click="play">PLAY</b-button>
</div>
</template>
b-button 是一个子组件,在我们的组件的单元测试中使用 shallowMount
时它被存根。这就是我们找不到元素按钮的原因:
const wrapper = shallowMount(MyComponent);
wrapper.find('button'); // won't work
我们可以这样找到子组件:
wrapper.find(BButton); // BButton has to be imported from bootstrap-vue
但是如果我们尝试输出呈现的元素:
console.log(wrapper.find(BButton).element);
我们将得到:
HTMLUnknownElement {}
作为子组件的 BButton
尚未完全呈现,DOM 树中没有 button
元素。但是当我们使用 mount
时,我们有这种行为:
const wrapper = mount(MyComponent);
console.log(wrapper.find(BButton).element);
我们将得到:
HTMLButtonElement { _prevClass: 'btn btn-primary' }
我们看到 mount
已经渲染了子组件。当我们使用 mount
时,我们可以直接访问 button
元素:
wrapper.find('button');
现在我们有了 button
,我们可以在上面触发类似 click
的事件。
我希望这对其他初学者也有帮助。这些示例非常简单,不要忘记使用 createLocalVue
创建 localVue
并将其传递给 mount
方法,如问题中所示。
使用BootstrapVue时请仔细考虑您需要哪种安装方法。
虽然仍在执行 shallowMount
,但您应该可以这样做:
wrapper.find(BButton).vm.$listeners.click();
这个问题让我很难过,我无法理解如何让 Vue Test Utils 和 BootstrapVue 一起玩得很好。
一个最小的例子是这样的:
MyComponent.vue
<template>
<div>
<b-button variant="primary" @click="play">PLAY</b-button>
</div>
</template>
<script>
export default {
name: 'MyComponent',
methods: {
play() {
console.log("Let's play!");
}
}
}
</script>
在main.js
中我们使用BootstrapVue:Vue.use(BootstrapVue)
.
这就是我尝试测试 click
事件是否已被触发的方式:
import { expect } from 'chai';
import sinon from 'sinon';
import Vue from 'vue';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import BootstrapVue, { BButton } from 'bootstrap-vue';
import MyComponent from '@/components/MyComponent.vue';
const localVue = createLocalVue();
localVue.use(BootstrapVue);
describe('MyComponent.vue', () => {
it('should call the method play when button is clicked', () => {
const playSpy = sinon.spy();
const wrapper = shallowMount(MyComponent, {
localVue,
methods: {
play: playSpy,
},
});
wrapper.find(BButton).trigger('click');
expect(playSpy.called).to.equal(true);
});
});
这给了我:
AssertionError: expected false to equal true + expected - actual -false +true
我检查了 BButton
。
当 运行 测试时,我也没有在命令行上看到任何输出,我希望在其中执行此行:
console.log("Let's play!");
这是怎么回事?
无法触发事件 click
的原因是 shallowMount
与 mount
相比的工作方式。
我们知道,Vue Test Utils 提供了两种方法来挂载组件,即渲染模板和生成 DOM 树:
- 坐骑
- shallowMount
第一种方法mount
生成一棵完整的DOM树,遍历所有子组件。大多数时候这不是必需的,因此首选方法 shallowMount
- 它将子组件存根到父组件的下一级。
就我而言,这也是问题的根源。 BootstrapVue 提供组件,如 BButton
,可以在您自己的 Vue 模板中使用。这意味着在以下模板中:
<template>
<div>
<b-button variant="primary" @click="play">PLAY</b-button>
</div>
</template>
b-button 是一个子组件,在我们的组件的单元测试中使用 shallowMount
时它被存根。这就是我们找不到元素按钮的原因:
const wrapper = shallowMount(MyComponent);
wrapper.find('button'); // won't work
我们可以这样找到子组件:
wrapper.find(BButton); // BButton has to be imported from bootstrap-vue
但是如果我们尝试输出呈现的元素:
console.log(wrapper.find(BButton).element);
我们将得到:
HTMLUnknownElement {}
作为子组件的 BButton
尚未完全呈现,DOM 树中没有 button
元素。但是当我们使用 mount
时,我们有这种行为:
const wrapper = mount(MyComponent);
console.log(wrapper.find(BButton).element);
我们将得到:
HTMLButtonElement { _prevClass: 'btn btn-primary' }
我们看到 mount
已经渲染了子组件。当我们使用 mount
时,我们可以直接访问 button
元素:
wrapper.find('button');
现在我们有了 button
,我们可以在上面触发类似 click
的事件。
我希望这对其他初学者也有帮助。这些示例非常简单,不要忘记使用 createLocalVue
创建 localVue
并将其传递给 mount
方法,如问题中所示。
使用BootstrapVue时请仔细考虑您需要哪种安装方法。
虽然仍在执行 shallowMount
,但您应该可以这样做:
wrapper.find(BButton).vm.$listeners.click();