Как правильно смоделировать / заглушить объект маршрута Vuejs $ и передать его как глобальное свойство при монтировании моего компонента с помощью avoriaz?
Я настраиваю модульные тесты для приложения Vuejs, и у меня возникают некоторые проблемы с получением компонентов, которые требуют правильного монтирования экземпляра $route или $router.
Я смоделировал элемент router-link и объект $route, но когда я передаю их в компонент, я все равно получаю сообщение об ошибке:
ERROR LOG: '[Vue warn]: Error in render function: "TypeError: undefined is not an object (evaluating 'this.$route.path')"
Я уверен, что правильно следую за API avoriaz, но объект $route недоступен внутри компонента.
Ниже мой компонент и соответствующий тест. Ошибка возникает при попытке оценить вычисленное значение closePath.
<template>
<div class="upperlayer" v-on:scroll="handleScroll">
<router-link :to="closePath" class="upperlayer__close upperlayer__close--tr"><i class="material-icons">close</i></router-link>
<router-link :to="closePath" class="upperlayer__close upperlayer__close--bm"><i class="material-icons">close</i></router-link>
<router-link :to="closePath" class="upperlayer__close upperlayer__close--tl"><i class="material-icons">keyboard_arrow_left</i> Back</router-link>
<loader></loader>
<section class="cf w-100 mb5 mb6-l">
<div class="hero" v-bind:style="'background-image:url(' + banner_image + ')'"></div>
<div class="mw-none mw8-l center mb4 pb3-m mb5-l pb0-l">
<div class="w-70-l ph3 ph4-ns tl">
<h1 class="f2 f-subheadline-m f-headline-l lh-solid fw5 b-ns mb3 pb2 mb4-l pb0-l">{{title}}</h1>
<span class="meta-label meta-label--dark f7 f6 f5-l lh-copy">Published {{formatDate(date)}} <i class="material-icons">access_time</i> {{calcDuration(body)}} mins</span>
</div>
</div>
<div class="center tl pb5">
<div v-html="body" class="cms-content ph3 ph4-ns"></div>
<div class="mt5" ref="feedback"></div>
</div>
</section>
<comments :subject="sgid"></comments>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import store from '../stores'
import moment from 'moment'
import comments from './shared/comments'
import loader from './shared/loader'
import {bus} from '../application'
import 'moment/locale/en-gb'
moment.locale('en-gb')
export default {
store: store,
name: 'article',
data () {
return {}
},
computed: {
...mapGetters('article', [
'id',
'handle',
'title',
'date',
'body',
'banner_image',
'sgid'
]),
closePath: function () {
return this.$route.path.match(/^(.*)article\/(.*)$/)[1]
}
},
mounted: function () {
this.$store.dispatch('loader/LOADING')
this.$store.dispatch('article/LOAD', this.$route.params.handle).then(() => {
this.$store.dispatch('loader/LOADED')
this.$mixpanel.track('Viewed Article', { handle: this.handle, uuid: this.id })
}, () => {
this.$store.dispatch('flash/FLASH_ERROR', 'There was an error while trying to load the article')
})
const { Feedback } = global
var fb = new Feedback(this.$refs['feedback'], { user: this.$store.getters['profile/nameAndEmail'] })
fb.loadWidget()
},
methods: {
formatDate: function (date) {
return moment(date).format('MMMM Do YYYY')
},
calcDuration: function (string) {
if (string === null) return
const wordCount = string.split(' ').length
const textLength = wordCount / 275
const imageCount = string.split('<img ').length
const viewLength = imageCount * 0.12
const duration = Math.round(textLength + viewLength)
return duration
},
handleScroll: function () {
bus.$emit('upperlayerScroll')
}
},
components: { loader, comments }
}
</script>
Юнит тест
import Vue from 'vue'
import { expect } from 'chai'
import { shallow } from 'avoriaz'
import Article from '@/components/ArticlePage'
const routerLink = {
name: 'router-link',
render: h => h('div')
}
const $route = {
name: 'article',
path: '',
params: {
handle: 'lorem-ipsum'
}
}
describe('Article.vue', () => {
it('should have the mounted hook', () => {
expect(Article.mounted).to.be.a('function')
})
it('should render the correct title', () => {
Vue.component('router-link', routerLink)
const testTitle = 'Test title'
const ArticleComponent = shallow(Article, {
globals: { $route },
propsData: {
title: testTitle
}
})
expect(ArticleComponent.find('h1')[0].text()).to.equal(testTitle)
})
})
Любые идеи, почему переход в глобальных не работает, как ожидалось?