javascript - vue测试登录表单
问题描述
我用 vuejs 创建了一个登录表单。我是 vue 框架的新手,想为我的 api 调用编写一个测试。
这是表格:
<template>
<div>
<div class="col q-mb-md">
<div class="row">
<q-btn
@click="loginGoogle"
type="submit"
color="primary"
class="col"
name="login_google"
outline
size="lg"
label="Login with Google" />
</div>
</div>
<div class="col q-mb-md">
<div class="row">
<q-btn
type="submit"
color="primary"
class="col"
name="login_apple"
outline
size="lg"
label="Login with Apple ID" />
</div>
</div>
<form @submit.prevent="submitForm" class="q-mt-lg">
<div class="col q-mb-md">
<q-input
v-model="formData.email"
outlined
class="col"
label="Email"
ref="email"
stack-label
:rules="[ val => validateEmail(val) || 'Please enter a valid email address']"
lazy-rules />
</div>
<div class="col q-mb-md">
<q-input
v-model="formData.password"
type="password"
outlined
class="col"
label="Password"
ref="password"
stack-label
:rules="[ val => val.length >= 8 || 'Password must be at least 8 characters']"
lazy-rules />
</div>
<div class="row">
<q-btn
type="submit"
name="login"
class="login"
color="primary"
label="Login" />
</div>
</form>
</div>
</template>
带有 api 调用的操作方法:
submitForm () {
this.$refs.email.validate()
this.$refs.password.validate()
if (!this.$refs.email.hasError && !this.$refs.password.hasError) {
authService.login({ email: this.formData.email.toLowerCase(), password: this.formData.password })
.then((res) => {
this.$store.commit('SET_AUTH_USER')
localStorage.setItem('access_token', res.access_token)
localStorage.setItem('refresh_token', res.refresh_token)
this.$store.dispatch('GET_ME').then((me) => {
this.$router.push({ path: '/' })
})
}).catch((err) => {
if (err.status === 500) {
this.$swal({ icon: 'error', title: 'Something went wrong!' })
} else {
this.$swal({ icon: 'error', title: 'Wrong data!' })
}
})
}
}
我的 API 调用:
/**
* Send request for login user and set token in localstorage
*
* @param {String} email
* @param {String} password
* @returns {Object}
*/
async function login (data) {
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json'
},
body: `email=${data.email.trim()}&password=${data.password.trim()}`
}
const res = await fetch('http://localhost/api/login', requestOptions)
if ((await res.status) !== 200) {
// eslint-disable-next-line no-throw-literal
throw { status: res.status, message: res.statusText }
} else {
return await res.json()
}
}
我读到我必须从 vuex 商店模拟动作并触发动作。所以我的测试看起来像这样:
import Vuex from 'vuex'
import { mount, createLocalVue } from '@vue/test-utils'
import LoginComponent from '../components/Auth/Login'
const localVue = createLocalVue()
localVue.use(Vuex)
describe('Login form', () => {
it('calls the login action correctly', () => {
const loginMock = jest.fn(() => Promise.resolve())
const store = new Vuex.Store({
actions: {
// mock function
submitForm: loginMock
}
})
const wrapper = mount(LoginComponent, { localVue, store })
wrapper.find('form').trigger('submit.prevent')
expect(loginMock).toHaveBeenCalled()
})
})
测试失败:
Login form
✕ calls the login action correctly (50 ms)
● Login form › calls the login action correctly
expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
18 | const wrapper = mount(LoginComponent, { localVue, store })
19 | wrapper.find('form').trigger('submit.prevent')
> 20 | expect(loginMock).toHaveBeenCalled()
| ^
21 | })
22 | })
23 |
at Object.<anonymous> (src/specs/login.spec.js:20:23)
您能给我一个建议吗?我需要编写哪些测试(不仅是 for api 调用)以确保我的表单正常工作?谢谢!
解决方案
您必须等待触发器,因为它正在进行异步函数调用
await wrapper.find('form').trigger('submit.prevent')
然后
wrapper.$nextTick(() => {
expect(loginMock).toHaveBeenCalled()
})
推荐阅读
- python - 如何使用 Python 增加动态加载量?
- r - 从列表中删除“短”数据框
- reactjs - 如何从表单字段字符串中设置枚举值?
- php - Woocommerce 按 ID 更改产品价格
- c# - 适用于 Office 运行时的 Visual Studio 2010 工具 - 生命周期结束
- google-app-engine - 为 AppEngine 柔性环境实例设置“GOOGLE_APPLICATION_CREDENTIALS”
- python - 使用 gnuplot 和 Glade 绘图
- python - 只用熊猫返回一年中的最后一天?
- java - 向量替换自身内部的值而不访问它
- c# - C# 比较类型是否相等,将这些类型作为参数