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

如何在Vitest/Jest中Stub defineNuxtRouteMiddleware?

解决Nuxt中defineNuxtRouteMiddleware的Mock问题

问题背景

我有如下中间件代码:

import checkAuth from './callbacks/checkAuth';
export default defineNuxtRouteMiddleware(checkAuth);

已将defineNuxtRouteMiddleware调用与中间件逻辑分离,仅需测试该函数是否被传入有效参数调用,但测试失败,原因是defineNuxtRouteMiddleware未定义。尝试用vi.stubGlobal('defineNuxtRouteMiddleware', vi.fn());无效,求Mock方法。


解决方法

原因分析

defineNuxtRouteMiddleware是Nuxt注入的全局API,测试环境不会自动挂载,直接用vi.stubGlobal无效大概率是模块加载顺序问题——你的中间件模块在Stub执行前就已经被导入,导致Mock没生效。

方案1:Mock Nuxt的#app模块

直接Mock Nuxt提供的#app模块,确保导入中间件时能获取到Mock的函数:

// 测试文件顶部优先Mock
vi.mock('#app', () => ({
  defineNuxtRouteMiddleware: vi.fn((fn) => fn)
}));

// 导入相关模块
import checkAuth from '@/middleware/callbacks/checkAuth';
import '@/middleware/your-middleware-file'; // 替换成你的中间件文件路径

test('defineNuxtRouteMiddleware被传入checkAuth调用', () => {
  const { defineNuxtRouteMiddleware } = await import('#app');
  expect(defineNuxtRouteMiddleware).toHaveBeenCalledWith(checkAuth);
});

方案2:调整导入顺序,确保Stub先生效

如果不想Mock模块,可以在导入中间件前先Stub全局,或者用动态导入确保Stub执行在前:

test('验证参数传入', async () => {
  // 先Stub全局
  vi.stubGlobal('defineNuxtRouteMiddleware', vi.fn((fn) => fn));
  // 动态导入中间件,此时Stub已生效
  await import('@/middleware/your-middleware-file');
  const checkAuth = (await import('@/middleware/callbacks/checkAuth')).default;
  
  expect(defineNuxtRouteMiddleware).toHaveBeenCalledWith(checkAuth);
});

方案3:用Nuxt官方测试工具简化操作

如果是Nuxt 3项目,推荐使用@nuxt/test-utils,它会自动模拟Nuxt的全局API,无需手动Stub:

import { describe, test, expect, vi } from 'vitest';
import { setup } from '@nuxt/test-utils';

// 先初始化Nuxt测试环境
await setup({
  // 可根据项目配置添加测试环境参数
});

test('中间件正确调用defineNuxtRouteMiddleware', async () => {
  // 监听defineNuxtRouteMiddleware方法
  const { defineNuxtRouteMiddleware } = await import('#app');
  const mockFn = vi.spyOn(await import('#app'), 'defineNuxtRouteMiddleware');
  
  // 导入中间件
  await import('@/middleware/your-middleware-file');
  const checkAuth = (await import('@/middleware/callbacks/checkAuth')).default;
  
  expect(mockFn).toHaveBeenCalledWith(checkAuth);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:33:21