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

Jest测试套件运行失败报EADDRINUSE错误:如何正确关闭server?

问题原因
  • 核心诱因是app.run.js的顶层直接执行了app.listen():测试文件导入app.run时会立刻启动服务占用8081端口,不等beforeAll钩子执行就已经触发端口占用。
  • 多测试文件并行执行时,即使单文件有关闭逻辑,同时启动的服务也会抢占同一端口触发报错。
  • 现有afterAll钩子中先关闭数据库再关闭服务的执行顺序,可能导致服务关闭逻辑执行异常。
修复方案

1. 调整app.run.js的启动逻辑

将端口监听逻辑包裹在运行判定中,仅当该文件被直接作为启动入口执行时才启动服务,被测试文件导入时仅返回app实例:

app.use('/api', require('./app.routes'));

// 新增判断:仅直接执行该文件时才启动监听
if (require.main === module) {
  app.listen(process.env.APP_PORT, () => {
    logger.info('Server is running on port ' + process.env.APP_PORT);
  });
}

module.exports = app;

2. 优化测试文件的生命周期钩子

修改afterAll执行顺序,等待服务完全关闭后再断开数据库连接,同时可传入端口0让系统自动分配随机端口,完全避免多文件并行的端口冲突:

const supertest = require('supertest');
const app = require('../../app.run');

let request = null;
let server = null;

beforeAll((done) => {
    // 传0则系统自动分配空闲端口,无需固定端口
    server = app.listen(0, done);
    request = supertest.agent(server);
});

afterAll((done) => {
    // 先关闭服务,再断开数据库连接
    server.close((err) => {
        sequelize.close();
        done(err);
    });
});

3. 可选兜底方案

如果需要保留固定端口测试,可在执行jest命令时添加--runInBand参数,强制所有测试用例串行执行,避免同时启动多个服务抢占端口:

jest --runInBand

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:54:03