2

I am writing unit tests for a Vue.js component that displays some radiobuttons and emits an event with the radio button id whenever a button is checked:

ApplicationElement.vue:

<template>
  <div id="element">
    <label>
      <input
        type="radio"
        name="Element"
        id="element1"
        v-on:change="chooseElement"
      />
      Element1
    </label>
    <label>
      <input
        type="radio"
        name="Element"
        id="element2"
        v-on:change="chooseElement"
      />
      Element2
    </label>
    <label>
      <input
        type="radio"
        name="Element"
        id="element3"
        v-on:change="chooseElement"
      />
      Element3
    </label>
    <label>
      <input
        type="radio"
        name="Element"
        id="element4"
        v-on:change="chooseElement"
      />
      Element4
    </label>
  </div>
</template>

<script>
export default {
  methods: {
    chooseElement () {
      var chosenElement = document.querySelector('input[name="Element"]:checked').id
      this.$emit('passChosenElement', {category: chosenElement})
    }
  }
}
</script>

<style>
</style>

I wrote the following test for said component:

ApplicationElement.spec.js:

import { shallowMount, createLocalVue } from '@vue/test-utils'
import 'regenerator-runtime/runtime'
import ApplicationElement from '@/components/ApplicationElement.vue'

const localVue = createLocalVue()

describe('ApplicationElement tests', () => {
    it('should emit event with element1 parameter on corresponding radio button choice', async() => {
        const wrapper = shallowMount(ApplicationElement, {
            localVue,
            attachTo: document.body,
            propsData: {
                recursionNumber: 1
            }
        })
        await wrapper.find('input[type="radio"][id="element1"]').setChecked()
        expect(wrapper.emitted().passChosenElement[0]).toEqual([{element: 'element1'}])
        wrapper.destroy()
    })
})

The test fails with: "TypeError: Cannot read property 'id' of null" If I remove the document.querySelector line from the chooseElement method in the component and emit the right id by hand, the test succeeds.

How can I get document.querySelector to work with vue-test-utils?

1 Answer 1

5

I know, this question is already a bit older, but I finally found a solution here. You need to attach your component with attachTo (since May 2021) to an html element. The solution looks like this:

describe('ApplicationElement tests', () => {
  it('should emit event with element1 parameter on corresponding radio button choice', async() => {
      const elem = document.createElement('div')
      if (document.body) {
         document.body.appendChild(elem)
      }

      const wrapper = shallowMount(ApplicationElement, {
          localVue,
          propsData: {
              recursionNumber: 1
          },
          attachTo: elem,
      })
      await wrapper.find('input[type="radio"][id="element1"]').setChecked()
      expect(wrapper.emitted().passChosenElement[0]).toEqual([{element: 'element1'}])
      wrapper.destroy()
  })
});
   

As you already did, it is important to call wrapper.destroy() after each test. Little refactoring tip: Put wrapper.destroy() into an afterEach callback function. Here you can find more about attachTo.

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

2 Comments

You are using attachTo twice in the same object. Could you remove the incorrect one?
Thank u for the hint @DrikusRoor. I removed it.

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.