我是Vue的新手,但是有一个带有登录页面的项目。我可以很好地运行它,但是我正在尝试对单元测试进行回溯添加(我知道,我正在反向进行此操作)。我正在使用Mocha + Chai和vue测试工具。当我尝试shallowMount时,出现一条错误消息,提示它无法读取属性。这是完整的错误文本:
1) Login
Has login text:
TypeError: Cannot read property 'email' of undefined
at Proxy.render (webpack:///./src/views/user/Login.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options:65:34)
at VueComponent.Vue._render (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:3640:22)
at VueComponent.updateComponent (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4168:21)
at Watcher.get (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4582:25)
at new Watcher (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4569:45)
at mountComponent (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4175:3)
at VueComponent.Vue.$mount (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:8512:10)
at init (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:3232:13)
at createComponent (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:6053:9)
at createElm (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:6001:9)
at VueComponent.patch [as __patch__] (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:6611:7)
at VueComponent.Vue._update (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4039:19)
at VueComponent.updateComponent (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4168:10)
at Watcher.get (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4582:25)
at new Watcher (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4569:45)
at mountComponent (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:4175:3)
at VueComponent.Vue.$mount (webpack:///./node_modules/vue/dist/vue.runtime.esm.js?:8512:10)
at mount (webpack:///./node_modules/@vue/test-utils/dist/vue-test-utils.js?:13265:21)
at shallowMount (webpack:///./node_modules/@vue/test-utils/dist/vue-test-utils.js?:13278:10)
at Context.eval (webpack:///./tests/unit/login.spec.js?:17:87)
at processImmediate (internal/timers.js:439:21)
这是我的包裹文件:
{
"name": "client",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"test": "mochapack --webpack-config webpack.config.js --require tests/setup.js tests/**/*.spec.js"
},
"dependencies": {
"axios": "^0.19.2",
"core-js": "^3.6.4",
"vue": "^2.6.11",
"vue-axios": "^2.1.5",
"vue-router": "^3.1.5",
"vuelidate": "^0.7.5",
"vuetify": "^2.1.0",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.0",
"@vue/cli-plugin-e2e-cypress": "^4.2.0",
"@vue/cli-plugin-router": "^4.2.0",
"@vue/cli-plugin-unit-mocha": "^4.2.0",
"@vue/cli-plugin-vuex": "^4.2.0",
"@vue/cli-service": "^4.2.0",
"@vue/test-utils": "^1.0.0-beta.31",
"chai": "^4.1.2",
"jsdom": "^16.1.0",
"jsdom-global": "^3.0.2",
"mocha": "^7.0.1",
"mochapack": "^1.1.13",
"node-sass": "^4.12.0",
"sass": "^1.19.0",
"sass-loader": "^8.0.2",
"vue-cli-plugin-vuetify": "^2.0.4",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.3.0"
}
}
这是我的组件代码:
<template>
<v-container fluid fill-height>
<v-layout align-center justify-center>
<v-flex xs12 sm8 md4>
<v-card class="elevation-12">
<v-toolbar color="primary" dark flat>
<v-toolbar-title>Login form</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form @submit.prevent="login">
<v-text-field
autofocus
v-model="email"
label="Email"
prepend-icon="mdi-account-circle"
@blur="$v.email.$touch()"
/>
<div class="red--text text--lighten-1" v-if="$v.email.$error">
<div v-if="!$v.email.required">
<v-icon color="red">mdi-alert-circle-outline</v-icon>
Email is required
</div>
<div v-if="!$v.email.email">
<v-icon color="red">mdi-alert-circle-outline</v-icon>
Invalid email address.
</div>
</div>
<v-text-field
v-model="password"
:type="showPassword ? 'text' : 'password'"
label="Password"
prepend-icon="mdi-lock"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
@click:append="showPassword = !showPassword"
@blur="$v.password.$touch()"
/>
<div
class="red--text text--lighten-1"
v-if="$v.password.$error && !$v.password.required"
>
<v-icon color="red">mdi-alert-circle-outline</v-icon>
Password is required
</div>
<v-btn
type="submit"
color="success"
name="button"
:disabled="$v.$invalid"
>
Login now
</v-btn>
<v-btn
text
small
color="primary"
:to="{ name: 'forgotPassword' }"
>
Forgot your password?
</v-btn>
<div v-if="error" class="red--text text--lighten-1">
<v-icon color="red">mdi-alert-circle-outline</v-icon>
{{ getLoginErrorMsg() }}
</div>
</v-form>
</v-card-text>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import { required, email } from "vuelidate/lib/validators";
export default {
name: "Login",
data() {
return {
email: "",
password: "",
error: null,
showPassword: false
};
},
validations: {
email: {
required,
email
},
password: {
required
}
},
methods: {
login() {
console.log("Entering component login method");
this.$store
.dispatch("user/login", {
username: this.email,
password: this.password
})
.then(() => {
console.log(
'this.$store.getters["user/passwordChangeRequired"]' +
this.$store.getters["user/passwordChangeRequired"]
);
if (this.$store.getters["user/passwordChangeRequired"]) {
console.log("push to changePassword");
this.$router.push({ name: "changePassword" });
} else {
console.log("pushing to home");
this.$router.push({ name: "home" });
}
})
.catch(err => {
this.error = err.response;
});
},
getLoginErrorMsg() {
if (this.error.status == 401) {
return "Invalid username or password";
} else {
// return `Login failed: {this.error.statusText}`;
return "failed";
}
}
}
};
</script>
<style></style>
这是测试文件:
import { expect } from "chai";
import { mount, shallowMount } from "@vue/test-utils";
import Login from "../../src/views/user/Login.vue";
describe("Login", () => {
it("Has login text", () => {
// const wrapper = mount(Login);
const wrapper = shallowMount(Login);
// not getting here.
expect(2).to.equal(2);
});
});
注意:mount或shallowMount均不起作用。他们都抛出相同的错误。
这是我的webpack.config.js文件:
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
// this will apply to both plain `.js` files
// AND `<script>` blocks in `.vue` files
{
test: /\.js$/,
loader: 'babel-loader'
},
// this will apply to both plain `.css` files
// AND `<style>` blocks in `.vue` files
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
]
}
我已经花了几个小时在谷歌上搜索,但我真的找不到任何东西。因此,我显然正在做一些非常愚蠢的事情,因为似乎没有其他人遇到这个问题。请告诉我为什么它会引发此错误,并且无法将它们挂入或挂载该Vue组件。
答案 0 :(得分:1)
看来我的tests / unit / index.js缺少一些东西……我没有在那里的绒毛,我相信这就是问题所在。我将其更改为以下内容,现在可以使用:
// index.js
import Vue from 'vue';
import Vuetify from 'vuetify';
import VueRouter from 'vue-router';
import Vuelidate from "vuelidate";
Vue.config.productionTip = false;
Vue.use(Vuetify);
Vue.use(VueRouter);
Vue.use(Vuelidate);