问题
I'm using bootstrap as my design framework and have been using bootstrap-vue. Now I would like to implement some tests to go along with my components. I'm writing a very simple test to make sure a modal is opened. What do I use in vue-test-utils to open the bootstrap-vue modal?
I'm using the basics that come with Laravel, bootstrap-vue, vue-test-utils, mocha, and mocha-webpack.
I'm trying to open the modal with wrapper.find('#modal-1').trigger('click')
. I've tried using a directive <b-button v-b-modal.modal-1>
I've tried using an event <b-button @click="$bvModal.show('modal-1')">
. And lastly, I tried a regular button <button @click="showModal = true">
with this on the b-modal <b-modal v-model="showModal">
. I've also tried adding a $nextTick
in between the trigger and the assertion.
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);
});
});
I'm expecting the modal to be in the wrapper with expect(wrapper.contains('#modal-1')).toBe(true)
and this is where the assertion is failing.
回答1:
Use the attachToDocument: true
mount option, as modal needs to be in the document in order to open.
You can see how BootstrapVue tests their modals at https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/components/modal/modal.spec.js
回答2:
I was looking at the bootstrap-vue test on github as Troy suggested (https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/components/modal/modal.spec.js)
There you can see that they are using the prop static: true. Adding this to my code solved my problem.
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();
});
});
I had to select the modal by id
because the inner part is getting display: none
. When I put a data-qa
on the modal it sticks on the outer element which is not hidden itself. Another solution for that would be to select it the following way:
const modal = wrapper.find('[data-qa="modal"] .modal');
But I still get the following warning in my console:
[BootstrapVue warn]: observeDom: Requires MutationObserver support.
回答3:
In my case this work perfectly,
Here I have a b-modal in template with a id="modal-1"
and when the button is clicked bootstrap-vue modal is opened using showModal()
method.
Try this:
<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>
来源:https://stackoverflow.com/questions/56227464/how-do-you-open-a-bootstrap-vue-modal-with-vue-test-utils