gpt4 book ai didi

vue.js - Vue 单元测试失败,因为组件方法调用 this.$route.query - TypeError : Cannot read property 'query' of undefined

转载 作者:行者123 更新时间:2023-11-28 20:07:26 25 4
gpt4 key购买 nike

StackOverflow 的智慧在工作和工作之外的长期用户,但我第一次发布问题。这是一个里程碑!

我正在为一个大型 Vue 应用程序编写单元测试,我的一个组件使用了一种引用 $route 的方法,以确定是否正在传入查询参数/是否正在使用该参数。调用 this.$route.query.article_id 的方法效果很好,但是现在我正在测试,测试无法识别 this.$route.query

我曾尝试在使用 shallowMount 挂载我的 localVue 时模拟 $route 对象,如文档中所述,但它不起作用,我继续遇到相同的错误。

这是我的组件:

<template>
<b-container fluid>
<div class="content-page-header"></div>
<b-row>
<b-col cols="3" class="outer-columns text-center" style="color:grey">
<font-awesome-icon
:icon="['fas', 'newspaper']"
class="fa-9x content-page-photo mb-3 circle-icon"
/>
<br />
<br />Get practical tips and helpful
<br />advice in clear articles written
<br />by our staff's experts.
</b-col>
<b-col cols="6" v-if="articlesExist">
<h1 class="header-text">
<b>Articles</b>
</h1>
<div v-if="!selectedArticle">
<div v-for="article in articles">
<article-card :article="article" @clicked="onClickRead" />
<br />
</div>
</div>
<div v-else>
<router-link to="articles" v-on:click.native="setSelectedArticle(null)">
<font-awesome-icon icon="chevron-circle-left" />&nbsp
<b>Back to All Articles</b>
</router-link>
<article-header :article="selectedArticle" />
<br />
<span v-html="selectedArticle.text"></span>
</div>
</b-col>
<b-col cols="6" v-else>
<h1 class="header-text">
<b>Articles</b>
</h1>
<div class="text-center">Stay tuned for more Articles</div>
</b-col>
<b-col class="outer-columns">
<b class="text-color" style="font-size:14pt">Saved Articles</b>
<div v-for="article in userArticles">
<router-link
:to="{path:'articles', query: {article_id: article.article.id}}"
v-on:click.native="setSelectedArticle(article.article)"
>
<user-article :article="article.article" />
</router-link>
<br />
</div>
</b-col>
</b-row>
</b-container>
</template>

<script>
import ArticleCard from "./ArticleCard";
import UserArticle from "./UserArticle";
import ArticleHeader from "./ArticleHeader";
import { library } from "@fortawesome/fontawesome-svg-core";
import {
faNewspaper,
faChevronCircleLeft
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

library.add(faNewspaper, faChevronCircleLeft);

export default {
name: "Articles",

props: [],

components: {
ArticleCard,
ArticleHeader,
UserArticle,
library,
FontAwesomeIcon,
faNewspaper,
faChevronCircleLeft
},

mixins: [],

data() {
return {
selectedArticle: null
};
},

computed: {
articles() {
return this.$store.getters.articles.filter(article => article.text);
},
articlesExist() {
return Array.isArray(this.articles) && this.articles.length;
},
userArticles() {
return this.$store.getters.userArticles;
},
articleParam() {
return parseInt(this.$route.query.article_id);
}
},

methods: {
setSelectedArticle(article) {
this.selectedArticle = article;
},
onClickRead(article) {
this.selectedArticle = article;
}
},

mounted() {
if (this.articleParam) {
this.setSelectedArticle(
this.articles.filter(article => article.id === this.articleParam)[0]
);
}
}
};
</script>

<style lang="stylus" scoped>
.text-color {
color: #549DB0;
}

.header-text {
color: white;
margin-top: -50px;
margin-bottom: 20px;
}

.outer-columns {
background-color: #F2FBFD;
padding-top: 20px;
}

.nav-back {
color: #549DB0;
background-color: #F0FBFD;
padding: 5px;
}
</style>

这是我的测试:

import { shallowMount, createLocalVue } from '@vue/test-utils'
import VueRouter from 'vue-router'
import Articles from '../../../app/javascript/components/member-dashboard/Articles.vue'

const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(VueRouter)
localVue.use(BootstrapVue)

describe('Articles', () => {
let store
let getters
let state = {
articles: [
{
title: "Testing Vue Components"
},
{
title: "This One shows",
text: "<p>You can see me!</p>"
},
{
title: "Another One",
text: "<p>See me too!</p>"
}
],
userArticles: [
{article: {
title: "This One shows",
text: "<p>You can see me!</p>"
}},
{article: {
title: "Another One",
text: "<p>See me too!</p>"
}}
]
}

beforeEach(() => {
getters = {
articles: () => {
return state.articles
},
userArticles: () => {
return state.userArticles
}
}

store = new Vuex.Store({ getters })
})

it('only displays article with body text', () => {
const wrapper = shallowMount(Articles, {
store,
localVue
})

expect(wrapper.vm.articles.length).to.deep.equal(2)
})
})

正如我提到的,在浅山中,我试过这样做:

 const wrapper = shallowMount(Articles, {
store,
localVue,
mocks: {
$route: {
query: null
}
}
})

但我继续收到此错误:

TypeError: Cannot read property 'query' of undefined
at VueComponent.articleParam (webpack-internal:///1:107:35)

当我从 articleParam 方法中删除行 return parseInt(this.$route.query.article_id); 时,我的测试通过了。

如何绕过组件中对 this.$route.query 的调用?这对我的测试来说不是必需的,但会导致我的测试在安装组件时失败。

最佳答案

import import VueRouter from 'vue-router'; 在你的联合测试文件中并创建一个新的路由器对象,如 const router = new VueRouter(); 和在您的测试用例中使用它。

我在这里更新了代码:

import { shallowMount, createLocalVue } from '@vue/test-utils'
import VueRouter from 'vue-router'
import Articles from '../../../app/javascript/components/member-dashboard/Articles.vue'

const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(VueRouter)
localVue.use(BootstrapVue);
const router = new VueRouter();

describe('Articles', () => {
let store
let getters
let state = {
articles: [
{
title: "Testing Vue Components"
},
{
title: "This One shows",
text: "<p>You can see me!</p>"
},
{
title: "Another One",
text: "<p>See me too!</p>"
}
],
userArticles: [
{article: {
title: "This One shows",
text: "<p>You can see me!</p>"
}},
{article: {
title: "Another One",
text: "<p>See me too!</p>"
}}
]
}

beforeEach(() => {
getters = {
articles: () => {
return state.articles
},
userArticles: () => {
return state.userArticles
}
}

store = new Vuex.Store({ getters })
})

it('only displays article with body text', () => {
const wrapper = shallowMount(Articles, {
store,
router,
localVue
})

expect(wrapper.vm.articles.length).to.deep.equal(2)
})
})

关于vue.js - Vue 单元测试失败,因为组件方法调用 this.$route.query - TypeError : Cannot read property 'query' of undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57871940/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com