찾다

 >  Q&A  >  본문

Vitest의 Mock Vue RouterView/RouterLink(통합 API)

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

사용자를 다음 페이지로 리디렉션하는 헤더와 버튼이 포함된 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粉478188786P粉478188786283일 전524

모든 응답(1)나는 대답할 것이다

  • P粉759451255

    P粉7594512552024-03-28 00:46:02

    이것이 가능합니다.

    귀하의 예제와 공식 예제에는 중요한 차이점이 있습니다. 테스트 중인 구성 요소에서는 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수신된 값을 가져와야 합니다.

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

    으아아아

    조금 까다롭습니다.

    회신하다
    0
  • 취소회신하다