Vitest의 Mock Vue RouterView/RouterLink(통합 API)
P粉478188786
P粉478188786 2024-03-27 09:49:56
0
1
488

제목대로 보니까 이게 가능한가요?

사용자를 다음 페이지로 리디렉션하는 헤더와 버튼이 포함된 Vue 애플리케이션의 간단한 구성 요소를 테스트하려고 합니다. 버튼을 클릭하면 이벤트/메시지가 라우터로 전송되는지 테스트하고 대상 경로가 올바른지 확인하고 싶습니다.

애플리케이션은 다음과 같이 구성됩니다:

App.Vue - 항목 구성 요소

으아아아

router/index.ts - Vue 라우터 구성 파일

으아아아

HomeView.Vue - 앱 구성 요소의 RouterView 입구 보기

으아아아

ButtonRouterLink.vue

으아아아

CompositionAPI와 TypeScript를 사용한다는 점을 고려하면 Vitest 테스트에서 라우터를 시뮬레이션할 수 있는 방법이 있나요?

다음은 테스트 파일 구조의 예입니다(HomeView.spec.ts):

으아아아

vi.mock('vue-router'), vi.spyOn(useRoute,'push'), vue-router-mock 라이브러리 등 여러 가지 방법을 시도했지만 테스트를 실행할 수 없습니다. 라우터인 것 같습니다. 단지 사용할 수 없습니다.

업데이트됨 (15/04/23)

@tao의 제안에 따라 HomeView에서 클릭 이벤트를 테스트하는 것이 좋은 테스트가 아니라는 것을 깨달았습니다(테스트한 것은 내 앱이 아니라 라이브러리였습니다). 그래서 Vue RouterLink가 올바르게 렌더링되는지 확인하기 위해 ButtonRouterLink 테스트를 추가했습니다. , to 매개변수 사용:

으아아아

빈 HTML 문자열을 렌더링합니다""

으아아아

별로 도움이 되지 않는 Vue 경고(예상 유형이 지정되지 않음)와 함께:

<script setup lang="ts">
import { RouterView } from "vue-router";
import Wrapper from "@/components/Wrapper.vue";
import Container from "@/components/Container.vue";
import HomeView from "@/views/HomeView.vue";
</script>

<template>
  <Wrapper>
    <Container>
      <RouterView/>
    </Container>
  </Wrapper>
</template>

<style>

  body{
    @apply bg-slate-50 text-slate-800 dark:bg-slate-800 dark:text-slate-50;
  }

</style>

P粉478188786
P粉478188786

모든 응답(1)
P粉759451255

이것이 가능합니다.

귀하의 예제와 공식 예제에는 중요한 차이점이 있습니다. 테스트 중인 구성 요소에서는 RouterLink(或使用router.push 버튼을 사용하는 대신 중간 구성 요소에 배치했습니다.

이것이 단위 테스트를 어떻게 바꾸나요?

첫 번째 문제는 하위 구성 요소를 빈 컨테이너로 바꾸는 shallowMountshallowMount,它会用空容器替换子组件。在你的情况下,这意味着ButtonRouterLink不再包含RouterLink를 사용한다는 것입니다. 귀하의 경우 이는 ButtonRouterLink가 더 이상 RouterLink를 포함하지 않으며 클릭 이벤트와 관련하여 아무 작업도 수행하지 않고 클릭 이벤트만 수신함을 의미합니다.

이 문제를 해결하기 위한 옵션은 다음과 같습니다:

  • a) mount而不是shallowMount를 사용하여 단위 테스트 대신 통합 테스트로 전환하세요
  • b) 이 기능에 대한 테스트를 ButtonRouterLink的测试中。一旦测试了ButtonRouterLink的任何:to是否正确转换为{ name: to }并传递给RouterLink,你只需要测试这些:to是否正确传递给使用它们的任何组件中的<ButtonRouterLink />로 이동합니다.

이 기능을 자체 구성 요소로 이동할 때 발생하는 두 번째 문제는 약간 더 미묘합니다. 일반적으로 ButtonRouterLink에 대한 다음 테스트가 작동할 것으로 예상합니다.

으아아아

놀랍게도 이 테스트는 RouterLinkStub에서 수신되었다고 주장하는 것과 동일한 :to属性值不是{ name: RouterNames.GAME },而是'game',这是我传递给ButtonRouterLink的值。就像我们的组件从未将value转换为{ name: value }테스트에 실패했습니다.

아주 이상해요.
문제는 <RouterLink />恰好是我们组件的根元素。这意味着组件(<BottomRouterLink>)在DOM中被<RouterLinkStub>替换,但:to의 값을 전자에서 읽고 후자에서 읽지 않는다는 점입니다. 즉, 템플릿이 다음과 같다면 테스트는 성공할 것입니다.

으아아아

이 문제를 해결하려면 실제 RouterLink组件(来自vue-router),并找到,而不是找到RouterLinkStub。为什么?@vue/test-utils足够聪明,可以找到存根组件而不是实际组件,但是这样,.findComponent()只会匹配替换后的元素,而不是在它仍然是ButtonRouterLink(未处理)时。此时,:to的值已经被解析为RouterLink수신된 값을 가져와야 합니다.

전체 테스트는 다음과 같습니다.

으아아아

조금 까다롭습니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿