Heim  >  Fragen und Antworten  >  Hauptteil

Vue-Router-Simulation mit Vue-Test-Utils und Vitest

<p>Ich versuche die Logik zu verstehen, Vue-Router mit Vitest zu verspotten. </p> <p>Zu diesem Zweck habe ich versucht, meine Testumgebung anhand eines sehr einfachen Projekts einzurichten und zu simulieren. Wenn ich versuche, der offiziellen Dokumentation von Vue-Test-Utils zu folgen, erhalte ich immer eine Fehlermeldung. Ich weiß nicht, ob es daran liegt, dass sie Jest benutzen. </p> <p>Die Verwendung eines echten Vue-Routers hat mein Problem gelöst, aber ich denke, dass es besser ist, einen Vue-Router zu verspotten. </p> <p> Im Folgenden werde ich zunächst den Quellcode des Projekts und dann die Fehler mitteilen, die ich erhalten habe. </p> <h3>Home.vue</h3> <pre class="brush:php;toolbar:false;"><script setup lang="ts"> import {onMounted} aus „vue“; {useRoute} aus „vue-router“ importieren; const route = useRoute() onMounted(() => { console.log(route.query) }) </script> <Vorlage> <div>Home</div> </template></pre> <h3>首页.spec.ts</h3> <pre class="brush:php;toolbar:false;">import {expect, it, vi} from "vitest"; {mount} aus „@vue/test-utils“ importieren; Importieren Sie Home aus „../src/components/Home.vue“ it('Home Test', async () => { const wrapper = mount(Home) erwarten(wrapper.exists()).toBeTruthy() })</pre> <h3>vite.config.ts</h3> <pre class="brush:php;toolbar:false;">/// <referencetypes="vitest" /> importiere { defineConfig } aus 'vite' vue aus „@vitejs/plugin-vue“ importieren // https://vitejs.dev/config/ Standard exportieren defineConfig({ Plugins: [vue()], prüfen: { Umgebung: 'jsdom', include: ['./test/**/*.spec.ts'], ausschließen: ['node_modules', 'dist'], Globals: wahr } })</pre> <h3>我的错误消息如下:..</h3> <h3>我尝试过的方法</h3> <p>我尝试像下面这样模拟 vue-router</p> <pre class="brush:php;toolbar:false;">vi.mock('vue-router', () => ({ useRoute: vi.fn(), }))</pre> <p>或者只是</p> <pre class="brush:php;toolbar:false;">vi.mock('vue-router')</pre> <h4>这是我的最终 Home.spec.ts 文件</h4> <pre class="brush:php;toolbar:false;">import {expect, it, vi} from "vitest"; {mount} aus „@vue/test-utils“ importieren; Importieren Sie Home aus „../src/components/Home.vue“ vi.mock('vue-router') it('Home Test', async () => { const wrapper = mount(Home, { global: { Stubs: ["router-link", "router-view"] } }) erwarten(wrapper.exists()).toBeTruthy() })</pre></p>
P粉190883225P粉190883225442 Tage vor598

Antworte allen(1)Ich werde antworten

  • P粉294954447

    P粉2949544472023-08-26 00:01:26

    首先,我希望在 Home.vue 中看到 router-linkrouter-view

    <script setup lang="ts">
    import { onMounted } from 'vue';
    import { useRoute } from 'vue-router';
    
    const route = useRoute();
    
    onMounted(() => {
      console.log(route.query);
    });
    </script>
    
    <template>
      <router-link to="home">Go to home</router-link>
      <router-view />
    </template>
    

    因此,Home.spec.ts 应该是这样的:

    import { expect, it, vi } from 'vitest';
    import { mount } from '@vue/test-utils';
    import * as VueRouter from 'vue-router';
    import Home from '../src/components/Home.vue';
    
    describe('./path/to/Home.vue', () => {
      const useRouteSpy = vi.spyOn(VueRouter, 'useRoute');
      const getWrapper = () => mount(Home as any, {
        global: {
          stubs: {
            'router-link': { template: '<div/>' },
            'router-view': { template: '<div/>' },
          },
        },
      });
    
      it('the component should be mounted', () => {
        // ARRANGE
        const useRouteMock = useRouteSpy.mockImplementationOnce({ query: 'query' });
        // ACT
        const wrapper = getWrapper();
        // ASSERT
        expect(useRouteMock).toHaveBeenCalled();
        expect(wrapper.exists()).toBeTruthy();
      });
    });
    

    一些评论/建议:

    • 使用描述来界定测试上下文
    • 定义一个全局函数来挂载组件,重用而不是重复
    • 使用 .spyOn().mockImplementation...() 进行监视和模拟
    • 使用某种结构化/直接的方式来编写测试,例如 AAA [安排、行动、断言] 或 GWT [给定、何时、然后]。我已经测试了几年并且仍在使用它,它可以帮助我了解我正在测试的内容
    • 使用 .toHaveBeenCalled...() 检查模拟是否按预期工作
    • mount() 函数中的存根应与模板中使用的组件相关(因此,如果您不使用 ,它不应该被列为存根)

    希望有帮助, 干杯!

    Antwort
    0
  • StornierenAntwort