vue.js - Vue Test Utils - 无法正确挂载/浅挂载组件,包装器未定义
问题描述
我已经尝试了几乎所有我能想到的东西,但我无法正确安装/浅安装我的 vue 组件以进行正确测试。每次我 console.log 包装器时,我都会得到以下打印输出:
VueWrapper {
isFunctionalComponent: undefined,
_emitted: [Object: null prototype] {},
_emittedByOrder: []
}
这个问题类似于这里提出的这个问题:
我正在使用 Vuetify、Vuex 和 Vue 路由器。我的 test.spec.ts 如下:
import { shallowMount, createLocalVue, mount } from "@vue/test-utils"
import Vuex from "vuex"
import Vuetify from "vuetify"
import VueRouter from "vue-router"
import TheExamAnswer from "@/components/common/TheExamAnswer.vue"
describe("TheExamAnswer.vue", () => {
const localVue = createLocalVue()
let getters: any
let store: any
let vuetify: any
let router: any
beforeEach(() => {
localVue.use(Vuex)
localVue.use(Vuetify)
localVue.use(VueRouter)
getters = {
getExam: () => true,
}
store = new Vuex.Store({
modules: {
// Need to add FlightPlanning for name spacing
FlightPlanning: {
namespaced: true,
getters,
},
},
})
vuetify = new Vuetify()
router = new VueRouter()
})
it("Renders the element if the exam has been submitted", () => {
const wrapper = mount(TheExamAnswer, { localVue, store, router })
console.log("This is the HTML", wrapper.html())
expect(wrapper.text()).toContain("Show Answer")
})
})
我的视图组件非常简单,代码如下:
<template>
<div v-if="submitted" class="div">
<v-btn @click="answerHidden = !answerHidden" class="mb-10"
>Show Answer</v-btn
>
<div v-if="!answerHidden">
<slot name="questionAnswer"></slot>
</div>
</div>
</template>
<script>
export default {
data: () => {
return {
answerHidden: true,
}
},
computed: {
submitted() {
const exam = this.$store.getters["FlightPlanning/getExam"]
return exam.submitted
},
},
}
</script>
<style></style>
更新:我已经从下面的答案中添加了建议,但是现在我收到了以下消息。
TheExamAnswer.vue
✕ Renders the element if the exam has been submitted (49ms)
● TheExamAnswer.vue › Renders the element if the exam has been submitted
expect(received).toContain(expected) // indexOf
Expected substring: "Show Answer"
Received string: ""
38 | const wrapper = mount(TheExamAnswer, { localVue, store, router })
39 | console.log("This is the HTML", wrapper.html())
> 40 | expect(wrapper.text()).toContain("Show Answer")
| ^
41 | })
42 | })
43 |
at Object.it (tests/unit/test.spec.ts:40:28)
console.error node_modules/vuetify/dist/vuetify.js:43612
[Vuetify] Multiple instances of Vue detected
See https://github.com/vuetifyjs/vuetify/issues/4068
If you're seeing "$attrs is readonly", it's caused by this
console.log tests/unit/test.spec.ts:39
This is the HTML
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
如您所见,HTML 是空白的,因此我假设这也是它未能通过此测试的原因,因为接收到的字符串是“”。
解决方案 -
我想到了。该错误代表我没有正确查看计算属性的逻辑。
在我的测试中,我有:
getters = {
getExam: () => true,
}
在我的组件中,我有:
computed: {
submitted() {
const exam = this.$store.getters["FlightPlanning/getExam"]
return exam.submitted
},
如果您查看计算属性的逻辑,它将获取从 getter 返回的内容并将其分配给考试变量。最初我返回的是 true,因为这就是我希望 submit() 函数返回的意思,这意味着当我调用exam.submitted 时,我在一个布尔值上调用它,这显然给了我“未定义”。解决方案是准确返回计算属性旨在处理的内容,即一个对象,即 {submitted:true}
因此最终的测试看起来像这样并且返回了有效的 HTML。
import { shallowMount, createLocalVue, mount } from "@vue/test-utils"
import Vuex from "vuex"
import Vuetify from "vuetify"
import VueRouter from "vue-router"
import TheExamAnswer from "@/components/common/TheExamAnswer.vue"
const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(Vuetify)
localVue.use(VueRouter)
describe("test.vue", () => {
let getters: any
let store: any
let vuetify: any
let router: any
beforeEach(() => {
getters = {
getExam: () => {
return { submitted: true }
},
}
store = new Vuex.Store({
modules: {
// Need to add FlightPlanning for name spacing
FlightPlanning: {
namespaced: true,
getters,
},
},
})
vuetify = new Vuetify()
router = new VueRouter()
})
it("Renders the element if the exam has been submitted", () => {
const wrapper = mount(TheExamAnswer, { localVue, vuetify, store, router })
console.log("This is the HTML", wrapper.html())
})
})
这给了我以下结果:
console.log tests/unit/test.spec.ts:44
This is the HTML <div><button type="button" class="mb-10 v-btn v-btn--contained theme--light v-size--default"><span class="v-btn__content">Show Answer</span></button>
<!---->
</div>
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.235s
Ran all test suites.
解决方案
带有用于包装器或元素的奇怪输入的 console.log 是正常行为。我对您的组件进行了几次测试,一切正常。
it("Renders the element if the exam has been submitted", () => {
const wrapper = mount(TheExamAnswer, { localVue, store, router });
expect(wrapper.text()).toContain("Show Answer");
});
如果你想在你的包装器中 console.log html:
console.log(wrapper.html())
更新:原因,为什么wrapper.html()
返回空字符串v-if="submitted"
在你的根组件上。计算属性返回undefined
,因为getter返回true
,所以true.submitted
返回undefined
吸气剂test.spec.ts
:
getters = {
getExam: () => {
return { submitted: true };
}
};
推荐阅读
- java - 文件名中指定的逗号(,)使 curl 处理器无法发送请求
- reactjs - 更新时如何在firestore中设置方法后获取文档
- python - Python 检查:获取特定装饰器的参数
- prometheus - 如何仅为自定义命名空间发送 Prometheus 警报
- c++ - 自定义排序以意想不到的方式工作
- python - Python正则表达式检查字符问题,我做错了什么?
- javascript - Javascript - 动态获取行表的ID
- c# - 2 个 IntPtr 上的 C# XOR
- css - 如何使用 jsname 检查元素到 div 中?
- python - 使用更新的单元格引用复制引用不同工作表的公式