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

NestJS搭配SuperTest+Jest测试运行后不退出,如何存储接口返回值供后续用例使用

问题根源
  • 测试执行完成后,你初始化的Nest应用实例没有被手动关闭,端口监听、数据库连接等后台资源仍处于占用状态,导致Jest检测到活跃的异步句柄无法退出
  • 你直接返回request调用链能正常退出是因为supertest内部会在Promise完成后自动释放单次请求的相关资源,但这种写法没法捕获返回值存储token/id,不满足你的业务需求
规范解决方案

1. 测试前后正确管理Nest应用生命周期

在测试文件的beforeAll钩子中初始化Nest应用,在afterAll钩子中手动关闭应用、销毁相关资源,示例代码如下:

import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module';
import * as request from 'supertest';

describe('Auth API test', () => {
  let app;
  let token; // 全局存储需要复用的token/id

  beforeAll(async () => {
    // 初始化测试模块
    const moduleFixture = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });

  // 测试跑完后手动关闭应用释放资源
  afterAll(async () => {
    await app.close();
  });

  it('/auth/register (POST)', async () => {
    const res = await request(app.getHttpServer())
      .post('/api/auth/register')
      .send({username: "Zoe"})
      .expect(201);
    token = res.body.token; // 正常获取返回值即可
  });

  // 后续测试用例可以直接复用存储的token
  it('/auth/profile (GET)', async () => {
    const res = await request(app.getHttpServer())
      .get('/api/auth/profile')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);
    // 此处编写断言逻辑
  });
})

2. 额外资源释放补充

如果你的应用里有数据库连接、Redis连接等长连接资源,在afterAll钩子中也要同步关闭,比如使用TypeORM的场景可以加:

afterAll(async () => {
  await app.get(Connection).close();
  await app.close();
})

3. 问题定位补充配置

如果还有偶现的退出问题,可以在jest配置中加detectOpenHandles: true定位具体未释放的句柄,不建议直接使用forceExit配置,强制退出会掩盖真实的资源泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:09:03