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

Express API测试遇Jest进程终止/段错误问题求助

Express API Jest测试Redis连接导致SIGSEGV问题解决

问题现象

  • 基于Express开发的API,使用Jest+Supertest做接口测试时,仅在VSCode打开状态下运行测试会触发SIGSEGV错误,外部终端运行测试全部正常
  • 核心报错信息:
FAIL  src/modules/ingredients/tests/updateingredient.test.ts
  ● Test suite failed to run

    A jest worker process (pid=672269) was terminated by another process: signal=SIGSEGV, exitCode=null. Operating system logs may contain more information on why this occurred.

      at ChildProcessWorker._onExit (node_modules/jest-worker/build/workers/ChildProcessWorker.js:366:23)

(node:672290) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 open listeners added to [_0x323dee]. Use emitter.setMaxListeners() to increase limit
(Use `node --trace-warnings ...` to show where the warning was created)
  • 用--detectOpenHandles排查:VSCode环境下输出Segmentation fault (core dumped),外部终端显示Redis连接的TCPWRAP未正确关闭

已尝试无效的方案

  • 在Jest的afterAll钩子中使用多种方式关闭Redis连接(直接调用redis.quit()、监听end事件等待连接关闭)
  • 重装VSCode、Node.js,更换多个Node版本
  • 执行npm rebuild、卸载VSCode Jest扩展、删除node_modules后重装全部依赖

根本原因

Redis单例在测试套件间共享,每个测试文件导入时都会直接创建连接,且测试结束后未彻底销毁实例,导致连接泄漏;VSCode环境下Jest的worker进程管理机制加剧了连接竞争,触发内存访问错误(SIGSEGV)。

解决方案

1. 将Redis单例改为延迟初始化

避免模块加载时立即创建连接,改为按需获取实例,同时提供清理方法:

// src/utils/redis.ts
import Redis from 'ioredis';
import config from 'config';
import { Logger } from 'src/logger/logger';

const redisDb = config.get<number>('redis_db');

let redisInstance: Redis | null = null;

export const getRedis = () => {
  if (!redisInstance) {
    redisInstance = new Redis({
      port: 6379,
      host: '127.0.0.1',
      db: redisDb,
    });

    redisInstance.on('ready', () => Logger.info('redis ready'));
    redisInstance.on('error', (error) => {
      Logger.error(`error with redis connection: ${error}`);
      redisInstance?.disconnect();
    });
  }
  return redisInstance;
};

// 用于测试时销毁实例
export const closeRedis = async () => {
  if (redisInstance) {
    await redisInstance.quit();
    redisInstance = null;
  }
};

2. 全局测试钩子统一管理Redis连接

在Jest配置中添加全局初始化文件,统一处理测试后的连接清理:

// jest.config.js
module.exports = {
  // 其他原有配置
  setupFilesAfterEnv: ['<rootDir>/src/test/setup.ts'],
};
// src/test/setup.ts
import { closeRedis } from '../utils/redis';

afterAll(async () => {
  await closeRedis();
});

3. 替换所有Redis实例引用

将项目中所有直接导入redis的地方,改为调用getRedis()获取实例:

// 示例:ingredients.controller.ts
import { getRedis } from 'src/utils/redis';

// 使用Redis时
const redis = getRedis();
await redis.setex(`ingredients_allergen_${parsedNames}`, 3600, JSON.stringify(foundIngredients));

4. 调整Jest配置减少进程冲突

在jest.config.js中添加以下配置,避免多worker进程的连接竞争:

module.exports = {
  // 其他原有配置
  maxWorkers: 1, // 单worker运行测试
  detectOpenHandles: true,
};

验证结果

  • VSCode打开状态下运行所有测试,无SIGSEGV错误和内存泄漏警告
  • 再次执行--detectOpenHandles检测,无未关闭的TCPWRAP连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:55:02