簡體   English   中英

用懸念測試 Vue3 異步設置組件的正確方法是什么?

[英]What is the proper way to test Vue3 async setup component with suspense?

毫無疑問,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

https://github.com/vuejs/vue-test-utils/issues/956

經過調查,寫了一個小助手,引用自上面的 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
      })
  })

選項不是可迭代的,刪除傳播。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM