6

I'm using the Buefy CSS Framework, which provides custom vue-js components such as <b-input> and <b-table>, and I've come across a problem testing the <b-input> tag.

import { shallowMount, createLocalVue } from '@vue/test-utils'
import BInputPractice from '../BInputPractice.vue'
import Buefy from 'buefy'

const localVue = createLocalVue()
localVue.use(Buefy)

describe('b-input Practice', () => {
  it('updates the name data property', () => {
    const wrapper = shallowMount(BInputPractice, { 
      localVue,
      stubs: {
        'b-input': Buefy.Input
      } 
    })
    const input = wrapper.find('input')
    input.element.value = 'a name'
    input.trigger('input')
    expect(wrapper.vm.name).toBe('a name')
  })
})

<!-- BInputPractice.vue -->
<template>
  <div>
    <b-input v-model="name"></b-input>
    <!-- <input v-model="name"> -->
  </div>
</template>

<script>
  export default {
    data() {
      return {
        name: ''
      }
    }
  }
</script>

The expect statement in my test code should pass, as it passes when I use an <input> tag instead of a <b-input>. However, triggering the 'input' event on the <b-input> does nothing to the name data property.

enter image description here

Does anyone know how I can correctly stub the <b-input> tag so that I can test it exactly as an <input> tag?

Rich
  • 301
  • 4
  • 9

1 Answers1

1

I hope this will help a bit. I realised that when stubbed, a component's name change and -stub is added at the end.

So if you stub b-input it will be called b-input-stub when using:

const wrapper = shallowMount(BInputPractice, { stubs: ['b-input'] })

I don't thing you need to use localView and stubs at the same time. Also you can use the setData(data) to set the data of a component.

expect(wrapper.find('b-input-stub').exists()).toBeTruthy() 
wrapper.setData({ name: 'a name' })
expect(wrapper.vm.name).toEqual('a name')

Here the trigger('input') does not need to be launched because you didn't specify something to do @input.native in the b-input like in the template:

<b-input @input.native="updateName" v-model="name"> </b-input>

And inside the export default in your script.

methods: {
    updateName: function () {
      this.$emit('nameUpdate', this.name)
    }
  }

However to set and validate the value of custom components like b-input, I would refer to vuejs/vue-test-utils.

Sylhare
  • 5,907
  • 8
  • 64
  • 80