Javascript 无法在Jest中使用提交按钮触发Vuetify表单提交
我正在尝试使用Jest和Avoriaz验证基于Vuetify组件的Vue表单的行为。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
我可以在表单上触发
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()
等待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()
}
})
})