Модули Vuex в Nuxt не проходят тесты компонентов Jest - с помощью Vue Test Utils - PullRequest
0 голосов
/ 23 марта 2020

Я получаю следующие ошибки, пытаясь запустить довольно базовый c тест в Jest с vue -test-utils для nuxt. Я в некотором затруднении относительно того, почему, потому что я следовал советам test-utils к письму:

● Messages › is a Vue instance

    TypeError: Cannot read property 'length' of undefined



      at Proxy.render (pages/centres/_centreId/messages/index.vue:2169:68)
      at VueComponent.Vue._render (node_modules/vue/dist/vue.common.dev.js:3547:22)
      at VueComponent.updateComponent (node_modules/vue/dist/vue.common.dev.js:4063:21)

  ...

  console.error node_modules/vuex/dist/vuex.common.js:1036
    [vuex] module namespace not found in mapGetters(): messages/


  console.error node_modules/vue/dist/vue.common.dev.js:630
    [Vue warn]: Error in render: "TypeError: Cannot read property 'length' of undefined"

    found in

    ---> <Anonymous>
           <Root>

  ...

  console.error node_modules/vue/dist/vue.common.dev.js:1893
    TypeError: Cannot read property 'length' of undefined

тест, который я запускаю, выглядит примерно так, как показано ниже:

import { shallowMount, createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'

import { cloneDeep } from 'lodash'

import index from '@/pages/centres/messages/index.vue'

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

describe('Messages', () => {
  let store
  const messages = [
    {
      foo: 'foo',
      bar: 'bar'
    }
  ]

  beforeEach(() => {
    store = new Vuex.Store(cloneDeep({
      modules: {
        messages: {
          actions: {
            'shiftMessage': () => []
          },
          getters: {
            'getFirst': () => messages[0],
            'messages': () => messages
          }
        }
      }
    }))
  })

  test('is a Vue instance', () => {
    const wrapper = shallowMount(index, { store, localVue })
    expect(wrapper.isVueInstance()).toBeTruthy()
  })
})

Если вам это нужно, вот упрощенная версия компонента

<template>
  <div class="Message">
    <form class="Message-body" @submit.prevent="resolveMessage">
      <div class="Message-bodyContent">{{ message.foo }} {{ message.bar }}</div>
      <next-button type="submit">Continue</next-button>
    </form>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

import NextButton from '~/components/layouts/NextButton'

export default {
  layout: 'portalClassic',
  components: { NextButton },
  fetch ({ store }) {
    store.dispatch('setLoading', false)
  },
  async asyncData ({ $axios, $grails, error, params, redirect, store }) {
    ... // sets store messages
  },
  computed: {
    ...mapGetters('messages', ['getFirst', 'messages'])
  },
  methods: {
    ...mapActions('messages', ['shiftMessage']),
    nextMessage () {
      return new Promise(function (resolve, reject) {
        try {
          this.shiftMessage()
          resolve(!!this.messages.length)
        } catch (e) { reject(e) }
      }.bind(this))
    },
    async resolveMessage () {
      try {
        const { centreId } = this.$route.params
        await this.$axios.put('foo/url', { ...this.$data })
        const hasNextMessage = await this.nextMessage()
        if (!hasNextMessage) this.$router.push(`/centres/${centreId}`)
      } catch (e) {
        throw this.$grails.formatHttpStatus(e)
      }
    }
  }
}
</script>
...