Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法在Jest中使用提交按钮触发Vuetify表单提交_Javascript_Vue.js_Jestjs_Vuetify.js - Fatal编程技术网

Javascript 无法在Jest中使用提交按钮触发Vuetify表单提交

Javascript 无法在Jest中使用提交按钮触发Vuetify表单提交,javascript,vue.js,jestjs,vuetify.js,Javascript,Vue.js,Jestjs,Vuetify.js,我正在尝试使用Jest和Avoriaz验证基于Vuetify组件的Vue表单的行为。 我可以在表单上触发submit.prevent,导致预期行为。 但是,在提交按钮上触发单击无效 组成部分: <template> <v-form ref="form" data-cy="form" @submit.prevent="login" > <v-text-field id="email" v-model="e

我正在尝试使用Jest和Avoriaz验证基于Vuetify组件的Vue表单的行为。
我可以在表单上触发
submit.prevent
,导致预期行为。
但是,在提交按钮上触发
单击
无效

组成部分:

<template>
  <v-form
    ref="form"
    data-cy="form"
    @submit.prevent="login"
  >
    <v-text-field
      id="email"
      v-model="email"
      label="Email"
      name="email"
      prepend-icon="mdi-at"
      type="text"
      required
      autofocus
      data-cy="email-text"
    />
    <v-btn
      color="primary"
      type="submit"
      data-cy="login-btn"
    >
      Login
    </v-btn>
  </v-form>
</template>

<script>

export default {
  data () {
    return {
      email: 'test@test.com',
    }
  },
  computed: {},
  methods: {
    login: function () {
      console.log('Logging in')
    }
  }
}
</script>
Vue&Vuetify设置在
@/plugins/Vuetify
中完成:

import Vue from 'vue'
import Vuetify from 'vuetify/lib'

Vue.use(Vuetify)

export default new Vuetify({
})
以下测试成功(因此模拟工作正常):

但实际测试提交按钮失败:

  it('can trigger form through button', () => {
    const login = jest.fn()
    const wrapper = mountFunction()
    wrapper.setData({ 'email': 'test@test.com' })
    wrapper.setMethods({ login })

    const button = wrapper.first('[type=submit]')
    button.trigger('click')

    expect(login).toHaveBeenCalledTimes(1)
  })
更新: 可能是
package.json
中的一些相关依赖项:

{
  ..
  "dependencies": {
    "axios": "^0.19.1",
    "core-js": "^3.4.4",
    "vue": "^2.6.11",
    "vue-router": "^3.1.3",
    "vuetify": "^2.1.0",
    "vuex": "^3.1.2"
  },
  "devDependencies": {
    ..
    "avoriaz": "^6.3.0",
    "vue-jest": "^3.0.5",
    "vuetify-loader": "^1.3.0"
  }
}
更新:
当使用测试util时,非Vuetify组件(
这可能是一个异步问题。我会在触发click事件之后和断言之前尝试等待
Vue.nextTick()

  it('can trigger form through button', async () => {
    const login = jest.fn()
    const wrapper = mountFunction()
    wrapper.setData({ 'email': 'test@test.com' })
    wrapper.setMethods({ login })

    const button = wrapper.first('[type=submit]')
    button.trigger('click')

    await Vue.nextTick()
    expect(login).toHaveBeenCalledTimes(1)
  })

显然,在使用Vuetify组件(
)时,有一些关键要素是使其工作所必需的:

  • Vue测试UTIL而不是avoriaz
  • mount
    而不是
    shallowMount
  • 包括
    attachToDocument
    ,这也需要随后进行清理(
    wrapper.destroy()
  • 正如@Husam Ibrahim也提到的,需要异步地等待Vue.nextTick()
  • 为了让setData完全生效,您可能需要额外的
    等待Vue.nextTick()
    。在我的完整代码中,我有表单验证(输入上有
    :规则
    ,表单上有
    v-model
    ,按钮的
    :禁用
    绑定到
    v-model
    数据元素。这需要两个
    nextTick()
    s
  • 以下工作(与问题中相同的
    @/plugins/vuetify'
    一起工作):

    import vuetify from '@/plugins/vuetify'
    import Vue from 'vue'
    import { createLocalVue, mount } from '@vue/test-utils'
    import Form from '@/views/Form'
    import Vuetify from 'vuetify/lib'
    
    const localVue = createLocalVue()
    
    localVue.use(Vuetify)
    
    describe('Form', () => {
      const mountFunction = options => {
        return mount(Form, {
          localVue,
          vuetify,
          ...options
        })
      }
      it('can trigger form through button alternative', async () => {
        const login = jest.fn()
        const wrapper = mountFunction({ attachToDocument: true })
        try {
          wrapper.setData({ 'email': 'test@test.com' })
          await Vue.nextTick() # might require multiple
          wrapper.setMethods({ login })
    
          const button = wrapper.find('[type=submit]')
          button.trigger('click')
          await Vue.nextTick()
    
          expect(login).toHaveBeenCalledTimes(1)
        } finally {
          wrapper.destroy()
        }
      })
    })
    

    我必须在“()=”之前添加
    async
    {`允许使用
    等待
    。但仍然只观察到0次登录调用。是否存在一些不确定的行为。我更改了测试,运行了它,观察到1次调用。然后进行了清理,没有使测试通过。恢复,然后再次失败。我的IntelliJ本地历史记录显示,使用您的代码,测试成功,但现在失败了。很抱歉获取了async关键字。如果涉及到任何不确定性行为,我会感到惊讶。您的代码和测试在我看来完全是确定性的。谢谢,不幸的是,无法使测试成功。很高兴您找到了解决方案:)对我来说,它仅使用
    mount
    而不是
    shallowMount
    const localVue = createLocalVue()
    
    localVue.use(Vuetify)
    describe('Form', () => {
      const mountFunction = options => {
        return shallowMount(Form, {
          localVue,
          vuetify,
          ...options
        })
      }
      it('can trigger form through button alternative', async () => {
        const login = jest.fn()
        const wrapper = mountFunction({ attachToDocument: true })
        try {
          wrapper.setData({ 'email': 'test@test.com' })
          wrapper.setMethods({ login })
    
          const button = wrapper.find('[type=submit]')
          expect(button).toBeDefined()
          button.trigger('click')
          await Vue.nextTick()
    
          expect(login).toHaveBeenCalledTimes(1)
        } finally {
          wrapper.destroy()
        }
      })
    })
    
      it('can trigger form through button', async () => {
        const login = jest.fn()
        const wrapper = mountFunction()
        wrapper.setData({ 'email': 'test@test.com' })
        wrapper.setMethods({ login })
    
        const button = wrapper.first('[type=submit]')
        button.trigger('click')
    
        await Vue.nextTick()
        expect(login).toHaveBeenCalledTimes(1)
      })
    
    import vuetify from '@/plugins/vuetify'
    import Vue from 'vue'
    import { createLocalVue, mount } from '@vue/test-utils'
    import Form from '@/views/Form'
    import Vuetify from 'vuetify/lib'
    
    const localVue = createLocalVue()
    
    localVue.use(Vuetify)
    
    describe('Form', () => {
      const mountFunction = options => {
        return mount(Form, {
          localVue,
          vuetify,
          ...options
        })
      }
      it('can trigger form through button alternative', async () => {
        const login = jest.fn()
        const wrapper = mountFunction({ attachToDocument: true })
        try {
          wrapper.setData({ 'email': 'test@test.com' })
          await Vue.nextTick() # might require multiple
          wrapper.setMethods({ login })
    
          const button = wrapper.find('[type=submit]')
          button.trigger('click')
          await Vue.nextTick()
    
          expect(login).toHaveBeenCalledTimes(1)
        } finally {
          wrapper.destroy()
        }
      })
    })