Как правильно смоделировать / заглушить объект маршрута 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)
  })
})

Любые идеи, почему переход в глобальных не работает, как ожидалось?

0 ответов

Другие вопросы по тегам