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

Nuxt3 Vitest Mock vue-router useRoute 第二个测试用例失败问题

问题原因

测试失败由两个问题共同导致:

  • vi.mock 存在提升机制,无论你把它写在文件哪个位置,都会被Vitest提前到文件最顶部执行,且模块被mock后会缓存。你把vi.mock写在两个单独的测试用例里,实际只有第一个mock定义会生效,第二个用例里的mock根本不会覆盖原有实现,两次调用useRoute拿到的都是第一个mock返回的{ params: { slug: 'abc' } },所以第二个用例拿到的计算结果还是/abc。
  • 你的断言和原代码逻辑不匹配:原组合式函数在slug不存在时返回的是undefined,你写的toBeNull()是判断返回值为null,本身就不符合代码实际行为。
修复方法
  1. 把vi.mock挪到文件顶层注册,不要写在单个用例内部,用一个可动态修改的变量存mock的路由状态,方便每个用例单独配置。
  2. 增加用例前置钩子,每个用例执行前重置路由状态,避免用例之间的状态污染。
  3. 修正第二个用例的断言,匹配代码实际返回的undefined。

修复后的测试代码:

import { vi, it, expect, describe, beforeEach } from 'vitest';
import useLinkToSlug from '~~/composables/useLinkToSlug';

// 定义可动态修改的mock路由对象
const mockRoute = {
  params: {
    slug: undefined
  }
}
// 顶层注册vue-router的mock
vi.mock('vue-router', () => ({
  useRoute: () => mockRoute
}))

describe('useLinkToSlug', () => {
  // 每个用例执行前重置slug状态,清除上一个用例的影响
  beforeEach(() => {
    mockRoute.params.slug = undefined
  })

  it('slug存在时返回拼接好的slug路径', () => {
    mockRoute.params.slug = 'abc'
    const link = useLinkToSlug();
    expect(link.value).toEqual('/abc');
  });

  it('slug不存在时返回undefined', () => {
    const link = useLinkToSlug();
    expect(link.value).toBeUndefined();
  });
});

如果是Nuxt3项目,也可以直接用官方测试工具@nuxt/test-utils提供的路由mock能力,不需要手动mock vue-router,兼容性更好。

内容的提问来源于stack exchange,提问作者floriankapaun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:30:57