Reputation: 323
I've been working with vuejs and bootstrap-vue lately. Decided to add unit testing to my project.
I'm not realy familiar with unit testing so I'm trying anything I could find to understand how it works.
Login.specs.js
import { shallowMount, mount } from '@vue/test-utils'
import Login from '@/components/auth/Login.vue'
describe('Login.vue', () => {
it('is a Vue instance', () => {
const wrapper = mount(Login, {
mocks: {
$t: () => 'Connexion' // i18N
}
})
const h2 = wrapper.find('h2')
expect(h2.text()).toBe('Connexion')
})
})
Login.vue
<b-row align-h="center">
<b-col class="text-center">
<h2>{{ $t('login.connection') }}</h2>
</b-col>
</b-row>
Everything seems ok with the test. But I got these wannings and could find a way to actualy fix it.
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
So I looked around and it seems like I need to add these child components to the father.
Here is the documentation for these components.
I'm also adding my config files (There're the same as the vue-cli 3 generates them)
jest.congif.js
module.exports = {
moduleFileExtensions: [
'js',
'jsx',
'json',
'vue'
],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest- transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: [
'jest-serializer-vue'
],
testPathIgnorePatterns: [ //I've added this one, not sure if usefull
'<rootDir>/node_modules'
],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
]
}
Upvotes: 19
Views: 10971
Reputation: 668
I see very inefficient import all components of boostrap-vue in each test.
You can add a file with all import and added into jest config file
jest.config.js
...
setupFiles: ['./jest/loadConfig.js'],
...
loadConfig.js
import Vue from 'vue';
import GlobalComponents from './plugins/globalComponents';
import BootstrapVue from 'bootstrap-vue';
Vue.use(BootstrapVue);
Vue.use(GlobalComponents);
and for end the plugin for global components
globalComponents.js
import { BRow, BCol } from 'bootstrap-vue'
const GlobalComponents = {
install(Vue) {
Vue.component('b-row', BRow);
Vue.component('b-col', BCol);
}
};
export default GlobalComponents;
Upvotes: 1
Reputation: 4863
Expanding on chrismarx answer.
Here is a example used in a vue/nuxt
application with bootstrap-vue
. While testing my component FormInput.vue
that has some elements from bootstrap-vue
, I was getting errors like Unknown custom element: <b-form-input>
and Unknown custom element: <b-col>
and Unknown custom element: <b-row>
Doc show example for using slots and custom components. I did the following to move past my errors. Note the bootstrap-vue
import and the stubs
section:
import { /* mount, */ shallowMount } from '@vue/test-utils'
import { BRow, BCol, BFormInput } from 'bootstrap-vue'
import FormInput from './FormInput.vue'
describe('FormInput test', () => {
test('is a Vue instance', () => {
const wrapper = shallowMount(FormInput, {
stubs: {
// used to register custom components
'b-form-input': BFormInput,
'b-row': BRow,
'b-col': BCol,
},
})
expect(wrapper.vm).toBeTruthy()
})
})
Upvotes: 6
Reputation: 1298
There are two options for this.
Firstly, If you use localVue
instance you have to register your bootstrap-vue component as global object using this localVue.component("b-breadcrumb", BBreadcrumb)
I will mention to
b-breadcrumb
as if it any part of boostrap-vue's components.
const localVue = createLocalVue()
localVue.component("b-breadcrumb", BBreadcrumb)
mount(CustomComponent, {
// Some options
})
Secondly, If you don't use localVue
instance you can register this component as a param of mount method like this
mount(CustomComponent, {
// Some options
components: {
BBreadcrumb
},
})
There is a important issue that If you use
localVue
instance components option of mount method will not work.
Also you can ignore any bootstrap-vue component to avoid unneccessary rendering using stubs
option of mount method.
mount(CustomComponent, {
stubs: ["b-breadcrumb"]
})
More information about options of mount here
Upvotes: 0
Reputation: 12555
If you're adding bootstrap vue as a global plugin:
Vue.use(BootstrapVue);
Then in your tests, you're likely going to want to follow this tip:
https://vue-test-utils.vuejs.org/guides/common-tips.html#applying-global-plugins-and-mixins
Which outlines how you can use the createLocalVue()
and set it up with the same global config as your app:
import { createLocalVue } from '@vue/test-utils'
// create an extended `Vue` constructor
const localVue = createLocalVue()
// install plugins as normal
localVue.use(BootstrapVue)
// pass the `localVue` to the mount options
mount(Component, {
localVue
})
Then your components should be registered properly-
Upvotes: 35
Reputation: 1440
It is also possible to stub components like
const wrapper = mount(Login, {
mocks: {
$t: () => 'Connexion' // i18N
},
stubs: {
BCol: true
}
});
Upvotes: 5