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

如何在Vitest中模拟AbortSignal.timeout接口函数?

问题分析与解决方案

你遇到的核心问题是:AbortSignal.timeout 是浏览器/Node.js 全局 API,并非你编写的 fetch.ts 模块导出的成员,所以你之前针对模块的 vi.mock 操作完全无效;同时 Vitest 默认运行在 Node 环境中,Node 18 以下版本原生不支持 AbortSignal.timeout,导致直接调用或模拟时抛出「不是函数」的错误。

下面是具体的修正方案:

正确模拟全局 AbortSignal.timeout

方案一:直接覆盖全局对象

在测试文件的开头或 beforeEach 钩子中,直接为全局 AbortSignal 添加 timeout 方法并模拟:

// 测试文件
import { fetchWithTimeout } from '~~/src/config/fetch';

describe('fetch 超时逻辑', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    // 模拟全局 AbortSignal.timeout,返回符合 AbortSignal 接口的对象
    global.AbortSignal = {
      ...global.AbortSignal,
      timeout: vi.fn(() => ({
        aborted: false,
        onabort: null,
        addEventListener: vi.fn(),
        removeEventListener: vi.fn(),
        dispatchEvent: vi.fn()
      })) as typeof AbortSignal.timeout
    };
  });

  it('应该调用 AbortSignal.timeout 并传入 8000', async () => {
    await fetchWithTimeout('https://example.com');
    expect(global.AbortSignal.timeout).toHaveBeenCalledWith(8000);
  });
});

方案二:使用 vi.spyOn(适用于 Node 18+ 环境)

如果你的测试环境是 Node 18 或以上(原生支持 AbortSignal.timeout),可以直接通过 spyOn 替换实现:

// 测试文件
import { fetchWithTimeout } from '~~/src/config/fetch';

describe('fetch 超时逻辑', () => {
  beforeEach(() => {
    vi.spyOn(global.AbortSignal, 'timeout').mockReturnValue({
      aborted: false,
      onabort: null,
      addEventListener: vi.fn(),
      removeEventListener: vi.fn(),
      dispatchEvent: vi.fn()
    });
  });

  afterEach(() => {
    vi.restoreAllMocks();
  });

  it('应该正确设置超时信号', async () => {
    await fetchWithTimeout('https://example.com');
    expect(AbortSignal.timeout).toHaveBeenCalledWith(8000);
  });
});

你之前的错误点总结

  1. 错误的 mock 目标:你尝试通过 vi.mock('~~/src/config/fetch') 模拟 AbortSignal,但 AbortSignal 是全局 API,并非该模块导出的内容,所以这种操作完全无效。
  2. 环境兼容性问题:Node 18 以下版本没有原生的 AbortSignal.timeout,直接调用 vi.spyOn(AbortSignal, 'timeout') 会因为方法不存在而报错,必须先在全局对象上定义该方法再模拟。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:22:17