Search code examples
vue.jsunit-testingbootstrap-vuestubvue-test-utils

Why Bootstrap-Vue tables (b-table) are mounted as "b-table-stub" in unit testing in @vue/test-utils , not just b-table?


I'm new to unit testing in Vue and I use @vue/test-utils. Here is my Foo.vue

<template>
  <div class="hello">
    <b-table striped hover :items="items"></b-table>
  </div>
</template>

<script>
export default {
  name: "Foo",
  data() {
    return {
      items: [
        {
          id: 0,
          name: "foo",
        },
        {
          id: 1,
          name: "bar",
        },
      ],
    };
  },
};
</script>

And here is my Foo.spec.js file for testing Foo.vue component:

import { shallowMount,createLocalVue } from '@vue/test-utils'
import Foo from '@/components/Foo.vue'
import {BootstrapVue} from "bootstrap-vue"

const localVue = createLocalVue();

localVue.use(BootstrapVue);

describe('Foo.vue', () => {
  it('renders bootstrap table', () => {
    const wrapper = shallowMount(Foo, {localVue})
    expect(wrapper.contains("b-table")).toBe(true)
  })
})

When I run the test I get the error;

● Foo.vue › renders bootstrap table

    expect(received).toBe(expected) // Object.is equality

    Expected: true
    Received: false

even though there must be a b-table element mounted. When I replace the code piece expect(wrapper.contains("b-table")).toBe(true) with expect(wrapper.contains("b-table-stub")).toBe(true) I didn't encounter any error.

Additionally when I remove the localVue asset from the shallowMount function like,

 const wrapper = shallowMount(Foo, {localVue})
 expect(wrapper.contains("b-table")).toBe(true)

no error remains and test case runs smoothly.

My question is that why b-table, b-pagination, etc. (b-x) elements are mounted as b-table-stub? Am I forced to check all b-x elements like b-x-stub in test cases or is there any shortcut for this?


Solution

  • You used shallowMount() to mount your component "Foo".

    Per vue-test-utils v2 docs shallowMount stubs child components so that you can focus on testing component Foo's logic without the need to mount child components and their children. This makes testing Foo's specific logic easier. Moreover, it makes the test more efficient since we are essentially building the DOM in memory and we can avoid unnecessarily rendering too much in memory by doing this.

    If you need to test b-table, use mount(Foo) instead. Further, if you want to test b-table only and ignore other components you can stub other child components like so:

    mount(Foo, {
      ...
      stubs: {
        childA: true,
        childB: true
      },
      ...
    })