【问题标题】:Mocking vue-router's useRoute() in Jest tests in Vue 3在 Vue 3 的 Jest 测试中模拟 vue-router 的 useRoute()
【发布时间】:2024-04-11 01:50:01
【问题描述】:

我在我的应用程序中使用 Vue 3 和 Vue-Router,但在使用 Jest 在使用 useRoute() 的组件上创建单元测试时遇到了问题,例如:

<template>
    <div :class="{ 'grey-background': !isHomeView }" />
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue';
import { useRoute } from 'vue-router';

export default defineComponent({
    setup: () => {
        const isHomeView = computed(() => {
            return useRoute().name === 'Home';
        });

        return {
            isHomeView,
        };
    },
});
</script>

computed 属性正在使用useRoute(),并且在模板中使用。 当我对此组件进行 Jest 测试时,会抛出一个错误,提示 TypeError: Cannot read property 'name' of undefined

我试着像这样嘲笑useRoutejest.mock('vue-router', () =&gt; ({ useRoute: jest.fn() })); 然后上beforeEachuseRoute.mockReturnValueOnce({ name: 'Home' });,但它不起作用。

我不是在谈论路由器工作方式不同的 Vue 2,而是 Vue 3。

【问题讨论】:

    标签: typescript vue.js jestjs vue-router vuejs3


    【解决方案1】:

    问题是你的工厂函数(即{ useRoute: jest.fn() })没有指定模拟返回(即,它返回undefined),所以useRoute().name试图从undefined访问name,这会生成你提到的错误。

    您可以更新模拟工厂以返回具有name 属性的对象:

    jest.mock('vue-router', () => ({
      useRoute: jest.fn(() => ({ name: 'Home' }))
    }))
    

    ...或者在测试中模拟它们而不是使用工厂:

    jest.mock('vue-router')
    
    describe('MyFoo.vue', () => {
    
      it('should have grey background for Home view', () => {
        require('vue-router').useRoute.mockReturnValueOnce({ name: 'Home' })
        const wrapper = shallowMount(MyFoo)
        expect(wrapper.html()).not.toContain('grey-background')
      })
    
      it('should not have grey background for non-Home view', () => {
        require('vue-router').useRoute.mockReturnValueOnce({ name: 'About' })
        const wrapper = shallowMount(MyFoo)
        expect(wrapper.html()).toContain('grey-background')
      })
    })
    
    

    【讨论】:

      最近更新 更多