javascript - 用悬念测试 Vue3 异步设置组件的正确方法是什么?
问题描述
毫无疑问,Suspense 特性会带来更简洁的代码库,但尽管它很整洁,但它变得难以测试。具体来说,它还没有很好的记录。
案子:
VUE CLI 生成的常规应用
- 技术栈:Vuex、Router、PWA、用于单元测试的笑话
挑战:
我使用了 Suspense 组件,推荐如下:
<RouterView name="default" v-slot="{ Component, route }">
<transition :name="route.meta.transition" mode="out-in" :duration="300" :key="route.path">
<Suspense >
<template #default>
<component :is="Component" :key="route.path"/>
</template>
<template #fallback>
<div class="top-0 right-0 h-screen w-screen z-50 flex justify-center items-center">
<div class="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-yellow-700"></div>
</div>
</template>
</Suspense>
</transition>
</RouterView>
我的路线和观点很少:
- 其中之一是用于登录视图
// here is the gotcha, if ever I removed async from setup the test runs well otherwise it always returns empty vm.
async setup(){
const router = useRouter()
const route = useRoute()
const form = reactive(new Form({
username:'',
password:'',
}))
}
我的测试套件如下:
test('Shows login form', async () => {
let wrapper = mount(Login,{
// tried set global.stubs.transition to false
renderDefaultSlot: true // tried as well to move this attr to beforeEach hook
})
expect(wrapper.exists()).toBe(true) // passes
await nextTick()
// tried to flushPromises()
console.log(wrapper.vm) // always empty object {}
expect(wrapper.findAll('div')).toBeTruthy() // fails accordingly as it can't run helper methods to get the parentElement
})
这里有没有VUE老手可以给点提示或者解决方法!
Github 上的所有公开讨论都表明,我并不是唯一一个偶然发现这个问题的人,但现在这只是一个讨论。
https://github.com/vuejs/vue-test-utils-next/issues/108#issue-611802592
解决方案
调查后写了一个小助手,上面引用了 Github 讨论:
import {defineComponent,h,Suspense } from 'vue'
import { mount } from '@vue/test-utils'
import flushPromises from 'flush-promises';
const mountSuspense = async (component, options) => {
const wrapper = mount(defineComponent({
render() {
return h(Suspense, null, {
default: h(component),
fallback: h('div', 'fallback')
})
}}), ...options)
await flushPromises()
return wrapper
}
describe('App renderes', ()=>{
test('About page renders',async()=>{
const wrapper = await mountSuspense(About)
await console.log(wrapper.text()) // it works
})
})
推荐阅读
- sql-server - TSQL - 在过程包含事务的事务中运行过程时出错
- python - 如何在 Python 中打开 .tsv 文件?
- ionic-framework - 如何获取元素中的属性值?
- powershell - 使用 Invoke-RestMethod 发布到 cosmosDB 返回 400
- sql-server - 为什么 EXCEPT 子句会在文本末尾修剪空白?
- android - 可以在外部存储上创建文件但不能创建目录
- c# - 为什么 Time.deltaTime 总是返回一个常量值 - 为什么当 Timescale 设置为 1 时它与 Time.unscaledDeltaTime 不同?
- python - package.egg-info 文件夹的用途是什么?
- python - 无法解析带有请求的图像
- sql - 按组起点的差异分组