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

Jest检测到open handles报错,使用bull的Node项目测试如何修复?

问题根因

Bull队列实例内部会维持和Redis服务的长连接用于任务调度、状态同步,测试执行完成后这些连接没有被主动释放,就会被Jest识别为未关闭的资源句柄,导致Jest无法正常退出。单纯的延时等待不会主动关闭这些连接,所以无法解决问题。

修复方案

方案1:主动关闭所有队列实例(最推荐)

你需要先将业务代码中实例化的队列导出,再在测试的afterAll钩子中主动调用队列的close()方法释放连接:

  1. 导出队列实例
// 原队列定义的文件中添加导出
export const csvExportsQueue = ['test', 'development'].includes(process.env.NODE_ENV) ? new Queue('exports') : new Queue('csv exports', 'redis://redis:6379/13');
  1. 在测试文件中关闭队列
import { csvExportsQueue } from './你的队列定义文件路径';

afterAll(async () => {
  // 关闭队列,释放Redis连接
  await csvExportsQueue.close();
  // 如果你有其他实例化的Bull队列,也依次调用close方法
  // await otherQueue.close();
});

如果测试中存在未处理的队列任务,可以先清空队列再关闭:

afterAll(async () => {
  await csvExportsQueue.obliterate({ force: true });
  await csvExportsQueue.close();
});

方案2:Mock Bull队列规避真实连接(单元测试推荐)

如果是单元测试场景,不需要真实调用Redis和队列逻辑,可以在Jest的全局配置文件/测试文件顶部Mock Bull库,完全规避真实网络连接的产生:

jest.mock('bull', () => {
  return jest.fn().mockImplementation(() => ({
    add: jest.fn(),
    process: jest.fn(),
    close: jest.fn().mockResolvedValue(true),
    // 补充其他你业务中用到的队列方法的Mock实现
  }));
});

方案3:强制Jest退出(临时兜底方案)

如果不需要严格校验资源释放,也可以在Jest启动参数中添加--forceExit强制测试跑完后直接退出进程,修改package.json中的测试命令即可:

{
  "scripts": {
    "test": "jest --forceExit"
  }
}

注意:该方案属于兜底手段,会掩盖其他未释放资源的问题,非必要不推荐使用

内容的提问来源于stack exchange,提问作者opensource-developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 06:06:03