3

由于在安装期间未在设置方法中定义路由对象,我无法在单元测试期间安装组件。这些指南似乎针对 Vue2 和 options API

参考

如何编写模拟 vue 组件中的 $route 对象的
测试 如何在 vue 组合 api 组件中使用 jest 进行单元测试?
https://vue-test-utils.vuejs.org/guides/#using-with-typescript
https://vue-test-utils.vuejs.org/guides/#using-with-vue-router

错误

● CoachItem.vue › displays alert when item is clicked

    TypeError: Cannot read property 'path' of undefined

      64 |       fullName: computed(() => props.firstName + " " + props.lastName),
      65 |       coachContactLink: computed(
    > 66 |         () => route.path + "/" + props.id + "/contact"

// @/tests/unit/example.spec.ts

import CoachItem from "@/components/coaches/CoachItem.vue"
import router from "@/router"


  describe("CoachItem.vue", () => {
    it("displays alert when item is clicked", async () => {

      //const route = { path: 'http://www.example-path.com' }
      router.push('/')
      await router.isReady()
      const wrapper = mount(CoachItem); //adding this line causes failure
      //await wrapper.trigger('click');
      //const dialog = wrapper.find('dialog');
      //(dialog.exists()).toBeTruthy()
    })
  })
// @/components/UserAlert.vue

<template>
  <div class="backdrop" @click="closeDialog"></div>
  <dialog open>
    <header>
      <h2>{{ title }}</h2>
    </header>
    <div>
      <slot name="content"></slot>
    </div>
    <menu>
      <button @click="closeDialog">Close</button>
    </menu>
  </dialog>
</template>

<script lang="ts>
import { defineComponent } from "vue";

export default defineComponent({
  props: ['title'],
  emits: ['close'],
  setup(_, context) {
    function closeDialog() {
      context.emit('close');
    }

    return { closeDialog };
  },
});
</script>
// @/components/coaches.CoachItem.vue

<template>
<user-alert v-if="alertIsVisible" title="Alert!" @close="hideAlert">
    <template v-slot:content><p>this is a slot</p></template>
  </user-alert>
  <li @click="showAlert">
    <h3>{{ fullName }}</h3>
    <h4>${{ rate }}/hour</h4>
    <div>
      <base-badge
        v-for="area in areas"
        :key="area"
        :type="area"
        :title="area"
      ></base-badge>
    </div>
    <div class="actions">
      <base-button mode="outline" link :to="coachContactLink"
        >Contact</base-button
      >
      <base-button link :to="coachDetailsLink">View Details</base-button>
    </div>
  </li>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, ref } from "vue";
import { useRoute } from "vue-router";
import useAlert from "../../components/hooks/useAlert";
export default defineComponent({
  props: {
    id: {
      type: String,
      required: true,
    },
    firstName: {
      type: String,
      required: true,
    },
    lastName: {
      type: String,
      required: true,
    },
    rate: {
      type: Number,
      required: true,
    },
    areas: {
      type: Object as PropType<Array<string>>,
      required: true,
    },
  },
  setup(props) {
    const route = useRoute();
    const alertTitle = ref("delete user?");
    return {
      fullName: computed(() => props.firstName + " " + props.lastName),
      coachContactLink: computed(
        () => route.path + "/" + props.id + "/contact"
      ),
      coachDetailsLink: computed(() => route.path + "/" + props.id),
      ...useAlert()
    };
  },
});
</script>
// @/main.ts
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import {store, key }  from "./store";
import UserAlert from "@/components/UserAlert.vue";

createApp(App)
.component('UserAlert', UserAlert)
  .use(store, key)
  .use(router)
  .mount("#app");
// @/router/index.ts

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

export default router;
4

0 回答 0