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

