在用vue-test-utils for nuxt在Jest中运行相当基本的测试时,我一直收到以下错误。我不知道为什么要这么做,因为我遵循了测试实用程序的建议:
● 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>