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

如何在Vitest中Mock相对路径请求解决URL类型报错

Vitest 相对路径请求Mock失效问题解决方案

问题根因

Vitest 默认运行在Node环境,底层使用node-fetch发起请求,该实现仅支持绝对URL,传入/oauth/token这类相对路径时会在参数校验阶段直接抛出TypeError: Only absolute URLs are supported,请求根本没走到MSW(setupServer为MSW提供的Mock能力)的拦截层,所以Mock逻辑不生效。

方案一:从根源修复,让Mock正常生效(推荐)

任选一种方法即可:

  • 方法1:切换测试环境为浏览器模拟环境(最省事)
    前端代码测试场景下,直接把Vitest测试环境换成happy-dom或jsdom即可,这两个环境模拟了浏览器的fetch实现,原生支持相对路径,MSW可正常拦截。

    1. 先安装对应依赖:
      npm i -D happy-dom
      # 或者选用jsdom:npm i -D jsdom
      
    2. 修改vitest.config.ts配置:
      import { defineConfig } from 'vitest/config'
      export default defineConfig({
        test: {
          environment: 'happy-dom', // 替换为'jsdom'效果一致,happy-dom运行速度更快
          // 原有setupFiles等配置保持不变
        }
      })
      

    配置完成后原有Mock代码不需要修改即可正常运行。

  • 方法2:Node环境下自动补全相对路径
    如果你必须使用node测试环境,可以在测试启动文件里重写全局fetch,自动给相对路径拼接虚拟域名,绕过node-fetch的参数校验,同时调整MSW的路径匹配规则支持跨域名匹配:

    1. 在vitest.config.ts中指定测试启动文件:
      import { defineConfig } from 'vitest/config'
      export default defineConfig({
        test: {
          setupFiles: ['./tests/setup.ts'],
        }
      })
      
    2. 在tests/setup.ts中添加fetch包装逻辑:
      const originFetch = globalThis.fetch
      globalThis.fetch = (input, init) => {
        if (typeof input === 'string' && input.startsWith('/')) {
          input = new URL(input, 'http://mock-local').toString()
        }
        return originFetch(input, init)
      }
      
    3. 修改MSW的handler路径,用通配符匹配任意域名下的接口:
      export const restHandlers = [
        // 路径前加*通配符,匹配任意域名下的/oauth/token接口
        rest.get('*/oauth/token', (_, res, ctx) => res(ctx.status(200), ctx.json(token))),
      ];
      

方案二:忽略对应未处理报错(临时方案)

如果你暂时不需要Mock这类接口,只想让测试不报错,可以修改server.listen的onUnhandledRequest配置,自定义过滤规则跳过这类请求的报错。
注意:该方案仅跳过MSW层的未处理请求报错,无法解决node-fetch本身抛出的URL格式错误,必须先按方法2的逻辑给相对路径补全为绝对路径才能生效。

beforeAll(() => server.listen({
  onUnhandledRequest: (req) => {
    // 匹配到/oauth开头的请求直接放行,不抛错
    if (req.url.pathname.startsWith('/oauth/')) return
    // 其他未匹配的请求仍然抛出错误
    throw new Error(`存在未Mock的请求: ${req.method} ${req.url.href}`)
  }
}))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:48:25