【问题标题】:vue-test-utils returns null for document.querySelectorvue-test-utils 为 document.querySelector 返回 null
【发布时间】:2026-01-01 14:35:01
【问题描述】:

我正在为 Vue.js 组件编写单元测试,该组件显示一些单选按钮并在选中按钮时发出带有单选按钮 ID 的事件:

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>

我为所述组件编写了以下测试:

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

测试失败:“TypeError: Cannot read property 'id' of null” 如果我从组件中的 chooseElement 方法中删除 document.querySelector 行并手动发出正确的 id,则测试成功。

如何让 document.querySelector 与 vue-test-utils 一起使用?

【问题讨论】:

    标签: javascript vue.js vue-test-utils


    【解决方案1】:

    我知道,这个问题已经有点老了,但我终于找到了解决方案here。您需要将带有 attachTo(自 2021 年 5 月起)的组件附加到 html 元素。解决方案如下所示:

    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,
              attachTo: document.body,
              propsData: {
                  recursionNumber: 1
              },
              attachTo: elem,
          })
          await wrapper.find('input[type="radio"][id="element1"]').setChecked()
          expect(wrapper.emitted().passChosenElement[0]).toEqual([{element: 'element1'}])
          wrapper.destroy()
      })
    });
       
    

    正如您已经做过的那样,每次测试后致电wrapper.destroy() 很重要。重构小技巧:将wrapper.destroy() 放入afterEach 回调函数中。在这里你可以找到更多关于attachTo的信息。

    【讨论】: