19

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)'
 ]
}
0

5 Answers 5

35

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-

Sign up to request clarification or add additional context in comments.

7 Comments

It still displays warns [BootstrapVue warn]: tooltip unable to find target element in document
i am facing the same issue and even after installing BootstrapVue plugin globally like this localVue.use(BootstrapVue) test run prints the warning in console "Unknown custom element: <b-alert> - did you register the component correctly? For recursive components, make sure to provide the "name" option." how to fix it? @BartusZak
It still displays warns for me. I did not find any solution :(
@BartusZak stubbing the bootstrap vue component on mount solves the issue .. there are not warning in the console.
@BartusZak I had the same issue and I also had to add await wrapper.vm.$nextTick() before expect(wrapper.element).toMatchSnapshot(). Sometimes I needed to add more than one await wrapper.vm.$nextTick() so all the children rendered. See how bootstrap-vue does it: github.com/bootstrap-vue/bootstrap-vue/blob/…
|
6

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()
  })
})

1 Comment

Only the above solution worked for me. I've tried initially to use the localVue() but it didn't work.
5

It is also possible to stub components like

const wrapper = mount(Login, {
  mocks: {
    $t: () => 'Connexion' // i18N
  },
  stubs: {
    BCol: true
  }
});

1 Comment

Thank you ! It kinda worked, i had 64 "errors", only 40 remains, some of them are b-cols or b-rows. I'll look it up later.
1

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;

Comments

0

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 localVueinstance 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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.