You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Vue.js3组合式API组件useRoute路由测试失败问题?

问题分析与解决方案

问题根源

你之前的Mock方式仅在全局挂载了route变量,但<script setup>中通过useRoute()获取的是Vue Router注入的路由实例,并非这个全局变量。第一个组件能生效是巧合:模板中的route.path在组件setup上下文的route变量(useRoute()返回的undefined)无法访问时,会 fallback 到全局Mock的route变量;而第二个组件的computed属性直接调用了setup中useRoute()返回的undefined对象,因此触发TypeError。

正确解决方案

方案1:Mock $route 注入变量(推荐,简单直接)

Vue Router会将路由实例以$route的形式注入组件,useRoute()本质是返回这个注入的实例。只需在测试中Mock$route即可:

let wrapper;

beforeEach(() => {
  wrapper = mount(HelloWorld, {
    props: {
      msg: 'Hello!'
    },
    global: {
      mocks: {
        $route: { path: '/hello' }
      }
    }
  });
});

此方案下,组件中useRoute()会直接返回Mock的$route对象,不管是模板直接使用还是computed属性中调用,都能正常获取path值。

方案2:Mock useRoute 函数(适合复杂场景)

如果需要更灵活控制useRoute()的返回值,可直接Mock该函数:

Mocha + Sinon 实现

import sinon from 'sinon';
import { useRoute } from 'vue-router';
import HelloWorld from '@/components/HelloWorld.vue';
import { mount } from '@vue/test-utils';

let useRouteStub;

beforeEach(() => {
  // 创建Stub,返回模拟路由对象
  useRouteStub = sinon.stub().returns({ path: '/hello' });
  // 替换vue-router中的useRoute
  Object.defineProperty(require('vue-router'), 'useRoute', { value: useRouteStub });
  
  wrapper = mount(HelloWorld, {
    props: { msg: 'Hello!' }
  });
});

afterEach(() => {
  // 恢复原函数,避免影响其他测试
  useRouteStub.restore();
});

手动Mock(无需Sinon)

import { useRoute } from 'vue-router';
import HelloWorld from '@/components/HelloWorld.vue';
import { mount } from '@vue/test-utils';

const originalUseRoute = useRoute;

beforeEach(() => {
  // 替换useRoute为自定义函数
  useRoute = () => ({ path: '/hello' });
  
  wrapper = mount(HelloWorld, {
    props: { msg: 'Hello!' }
  });
});

afterEach(() => {
  // 恢复原函数
  useRoute = originalUseRoute;
});

验证

使用上述任一方案后,第二个组件的computed属性path会正确读取到Mock的/hello路径,不再出现Cannot read properties of undefined错误。

内容的提问来源于stack exchange,提问作者Андрей Кондратов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:20:24