Как правильно протестировать компонент асинхронной настройки Vue3 с помощью suspense?

#javascript #ecmascript-6 #jestjs #vuejs3

#javascript #ecmascript-6 #jestjs #vuejs3

Вопрос:

Без сомнения, функция Suspense приводит к более чистой кодовой базе, но какой бы аккуратной она ни была, ее сложно протестировать. В частности, это еще недостаточно хорошо документировано.

случай:

Обычное приложение, созданное VUE CLI

  • Технический стек: Vuex, Router, PWA, jest для модульного тестирования

Задача:

Я использовал компонент 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

Ответ №1:

После расследования написал небольшой помощник, цитируемый из обсуждения на 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
      })
  })
 

Комментарии:

1. Спасибо, это было очень полезно, однако, похоже, это не так уж и важно, например, как мы можем проверить, что резервный вариант переопределяется?

2. @Mr.Toxy Экземпляр теперь существует в объекте-оболочке как wrapper.text() или wrapper.html () — Я советую вам console.log(оболочка) и имитировать асинхронный обратный вызов после ожидания flushPromises() или nextTick().

3. В итоге я обнаружил github.com/vuejs/vue-test-utils-next/blob/master/tests/features /… который работает безупречно

4. Я пытаюсь использовать этот код, но он не работает в строке : const wrapper = mount(defineComponent({ . При mount высказывании TypeError: Found non-callable @@iterator какой-либо помощи? 😅

5. @MarcPont кажется, что упомянутая выше ошибка заключается в том, что отсутствует зависимость или ошибка установки, какую тестовую среду вы используете. пожалуйста, ознакомьтесь с обновленной документацией VUE, это неплохо. и в качестве быстрого предупреждения используйте vue-cli для создания вашей тестовой структуры для вас. приветствия