如何使用 vue-test-utils 打开 bootstrap-vue 模态?
Posted
技术标签:
【中文标题】如何使用 vue-test-utils 打开 bootstrap-vue 模态?【英文标题】:How do you open a bootstrap-vue modal with vue-test-utils? 【发布时间】:2019-10-07 05:01:14 【问题描述】:我使用 bootstrap 作为我的设计框架,并且一直在使用 bootstrap-vue。现在我想实现一些测试来配合我的组件。我正在编写一个非常简单的测试来确保打开模式。在 vue-test-utils 中使用什么来打开 bootstrap-vue modal?
我正在使用 Laravel、bootstrap-vue、vue-test-utils、mocha 和 mocha-webpack 附带的基础知识。
我正在尝试使用wrapper.find('#modal-1').trigger('click')
打开模式。我尝试使用指令<b-button v-b-modal.modal-1>
我尝试使用事件<b-button @click="$bvModal.show('modal-1')">
。最后,我在 b-modal <b-modal v-model="showModal">
上尝试了一个常规按钮 <button @click="showModal = true">
。我还尝试在触发器和断言之间添加$nextTick
。
import createLocalVue, mount from '@vue/test-utils';
import expect from 'expect';
import BootstrapVue from 'bootstrap-vue';
import MyComponent from '@/components/MyComponent.vue';
const localVue = createLocalVue();
localVue.use(BootstrapVue);
describe ('MyComponent', () =>
let wrapper;
beforeEach(() =>
wrapper = mount(QuotesExceptions,
localVue
);
);
it ('opens a modal', () =>
expect(wrapper.contains('#modal-1')).toBe(false);
wrapper.find('#btnShow').trigger('click');
expect(wrapper.contains('#modal-1')).toBe(true);
);
);
我希望模态框包含在 expect(wrapper.contains('#modal-1')).toBe(true)
的包装器中,这就是断言失败的地方。
【问题讨论】:
您找到解决此问题的解决方案或变通方法了吗? 【参考方案1】:按照 Troy 的建议,我正在 github 上查看 bootstrap-vue 测试 (https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/components/modal/modal.spec.js)
在那里你可以看到他们正在使用道具static: true
。将此添加到我的代码中解决了我的问题。
component.vue
<b-modal
v-model="showModal"
id="myModal"
data-qa="importModal"
:static="true"
>
</b-modal>
component.spec.js
it ('opens a modal', (done) =>
const button = wrapper.find('[data-qa="button"]');
const modal = wrapper.find('#myModal');
expect(button.exists()).toBe(true);
expect(button.is('button')).toBe(true);
expect(modal.exists()).toBe(true);
expect(modal.is('div')).toBe(true);
expect(modal.isVisible()).toBe(false);
button.trigger('click');
Vue.nextTick(() =>
expect(modal.isVisible()).toBe(true);
done();
);
);
我必须通过id
选择模态,因为内部部分正在获取display: none
。当我在模态框上放置data-qa
时,它会粘在本身不隐藏的外部元素上。另一种解决方案是通过以下方式选择它:
const modal = wrapper.find('[data-qa="modal"] .modal');
但我仍然在控制台中收到以下警告:
[BootstrapVue warn]: observeDom: Requires MutationObserver support.
【讨论】:
在浪费了 2 天时间尝试多种解决方案之后,static: true
为我解决了这个问题! (我也收到了Requires MutationObserver support
warning。)【参考方案2】:
使用attachToDocument: true
挂载选项,因为模式需要在文档中才能打开。
您可以在 https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/components/modal/modal.spec.js 看到 BootstrapVue 如何测试他们的模式
【讨论】:
attachToDocument
现在已弃用,取而代之的是 attachTo
,它采用 htmlElment【参考方案3】:
it ('opens a modal', (done) =>
const button = wrapper.find('[data-qa="button"]');
expect(!!document.querySelector('myModal')).toBe(false)
button.trigger('click');
expect(!!document.querySelector('myModal')).toBe(true)
);
【讨论】:
口头解释通常很有帮助【参考方案4】:我正在使用 jest 来测试单击按钮时是否出现模式并最终出现相关问题。将我的答案留给未来的读者。
我试图做类似的事情:
let openModalBtn = wrapper.find('button[id="openModal"]');
expect(openModalBtn.exists()).toBe(true); // OK
expect(openModalBtn.is("button")).toBe(true); // OK
await deleteBtn.trigger("click"); // BANG
导致:
[Vue warn]: Error in v-on handler (Promise/async): "TypeError: this.$refs.confirmDialogue[0].show is not a function"
问题是我使用的是shallowMount
:
// not good
describe("some test", () =>
let wrapper;
beforeEach(() =>
wrapper = shallowMount(MyComponent, ...);
);
在MyComponent
的某个时刻,它需要执行以下操作:
...
methods:
openModal()
await this.$refs.confirmDialogue[0].show();
...
,
因此this.$ref
以undefined
的身份出现。
改用mount
:
// good
describe("some test", () =>
let wrapper;
beforeEach(() =>
wrapper = mount(MyComponent, ...);
);
允许我单击该按钮并在 wrapper.html()
中找到存根。
因此,如果您需要从中访问 stubs
,请确保安装您的组件。
【讨论】:
【参考方案5】:在我的情况下,这很完美,
这里我在模板中有一个 b-modal,带有 id="modal-1"
,当单击按钮时,使用 showModal()
方法打开 bootstrap-vue 模式。
试试这个:
<template>
<b-button v-on:click="showModal()">
<b-modal id="modal-1"></b-modal>
</template>
<script>
methods:
showModal()
this.$root.$emit("bv::show::modal", 'modal-1', "#btnShow");
,
</script>
【讨论】:
感谢您的建议。它确实在浏览器中完美运行。我的问题不在于模式在浏览器中不起作用。我似乎无法让 vue-test-utils 在我正在尝试编写的测试中打开模式。我已经用我试图在你显示的代码上运行的测试更新了我的问题。以上是关于如何使用 vue-test-utils 打开 bootstrap-vue 模态?的主要内容,如果未能解决你的问题,请参考以下文章
VueJs 如何删除全局错误处理程序以使用 vue-test-utils 进行测试
vue-test-utils:如何在 mount() 生命周期钩子(使用 vuex)中测试逻辑?
如何使用 vue-test-utils 在单元测试期间触发窗口事件
如何使用 Vue-test-utils 和 Jest 测试 Vuex 突变
如何在单元测试期间使用 vue-test-utils 和 jest 模拟 mixin?
如何使用 vue-test-utils 和 Jest 在 Nuxt 中对使用 vuex-module-decorators 语法定义的 Vuex 模块进行单元测试?