这个问题使我很难受,而且我不明白如何使 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
我检查了How to test for the existance of a bootstrap vue component in unit tests with jest?,但不适用于BButton
。
运行测试时,我也看不到命令行上的任何输出,我希望在该行上执行该操作:
console.log("Let's play!");
这是怎么了?
答案 0 :(得分:5)
无法触发事件click
的原因是与shallowMount
相比,mount
的工作方式。
我们知道,Vue Test Utils提供了两种安装组件的方法,即渲染模板并生成DOM树:
第一个方法mount
生成一个完整的DOM树并遍历所有子组件。在大多数情况下,这不是必需的,因此,方法shallowMount
是首选的-它在子组件的根目录仅比父组件低一级的地方进行存根。
就我而言,这也是问题的根源。 BootstrapVue 提供了BButton
之类的组件,可以在自己的Vue模板中使用它们。这意味着在以下模板中:
<template>
<div>
<b-button variant="primary" @click="play">PLAY</b-button>
</div>
</template>
b按钮是一个子组件,在我们的组件的单元测试中使用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
的事件。
我希望这也会对其他初学者有所帮助。这些示例非常简化,不要忘记使用localVue
创建createLocalVue
并将其传递给问题中说明的mount
方法。
使用 BootstrapVue 时,请仔细考虑所需的安装方法。
答案 1 :(得分:1)
在仍然执行shallowMount
的同时,您应该可以执行以下操作:
wrapper.find(BButton).vm.$listeners.click();