有没有办法通过点击Vue单元测试中的提交按钮来触发表单的提交?

让我们来看看这个简单的组件:

<template>
    <form @submit.prevent="$emit('submitEventTriggered')">
        <button type="submit">Submit Form</button>
    </form>
</template>

<script>
    export default {}
</script>

您可以找到与示例here类似的组件.

我想测试当点击按钮时submit.prevent被触发,因此submitEventTriggered被emits .当我在浏览器中运行此功能时,一切正常,但以下测试失败:

import {shallowMount} from '@vue/test-utils'
import {assert} from 'chai'
import Form from '@/components/Form.vue'

describe.only('Form', () => {

    it('button click triggers submit event', () => {
        const wrapper = shallowMount(Form)

        wrapper.find('[type=\'submit\']').trigger('click')

        assert.exists(wrapper.emitted('submitEventTriggered'), 'Form submit not triggered')
    })
})

通过此输出:

AssertionError: Form submit not triggered: expected undefined to exist

如果我改变动作,直接在表单上触发submit.prevent,一切正常,但实际上没有提交via按钮的测试覆盖率.

wrapper.find('form').trigger('submit.prevent')

似乎trigger函数实际上并没有点击按钮.

为什么会这样?有没有办法解决?

推荐答案

Note:之前的方法使用了attachToDocumentwhich has been deprecated


问题在于,默认情况下,Vue Test Utils不会将DOM node 附加到文档.这是为了避免强制清理.可以通过在安装组件时将attachTo设置为HTML元素来解决此问题:

const div = document.createElement('div')
div.id = 'root'
document.body.appendChild(div)

it('button click triggers submit event', () => {
  const wrapper = shallowMount(Form, {
    attachTo: '#root'
  })

  wrapper.find("[type='submit']").trigger('click')

  assert.exists(
    wrapper.emitted('submitEventTriggered'),
    'Form submit not triggered'
  )
})

应该从文档中删除DOM node ,以避免内存泄漏.您可以通过在包装器上调用destroy来实现这一点:

wrapper.destroy()

Vue.js相关问答推荐

将Vite Vuejs应用部署到Apache服务器

在哪里可以找到在线沙箱 Vuetify 3 模板来创建最小的可重现示例?

绑定事件在渲染函数中不起作用

仅在构建时为 Vue3 和 TailwindCSS 添加前缀

aspnet core如何在deploy上构建webpack

确保在渲染组件之前加载 Vuex 状态

将检测外部点击自定义指令从 Vue 2 迁移到 Vue 3

正确实现 Vue.js + DataTables

如何有条件地更改 vue/vuetify 文本字段 colored颜色

如何将参数传递给使用 ...mapActions(...) 映射的函数?

Vue&TypeScript:在项目目录外的 TypeScript 组件中实现导入时如何避免错误 TS2345?

错误:[vuex] 期望字符串作为类型,但发现未定义

加载时焦点文本框上的 Vue.js

在路由更改之前显示确认对话框

找不到模块 'babel-core' 但已安装 @babel/core

过渡后的 v-if 下方的过渡元素

如何让 Vue 在 shadow dom 中工作

如何在 VueJS 中下载本地存储的文件

如何在 vue.js 中进行嵌入?

如何设置 :id 前缀字符串?