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

NestJS中如何销毁测试模块?测试数据库相关问题咨询

Hey there! I totally get how tricky it can be to get started with testing when setup issues keep throwing you off. Let's break down those two TypeORM problems you're facing and fix them step by step.

Problem 1: Active Database Connection Persisting Between Tests

The error you're seeing happens because your test framework (like Jest or Mocha) isn't properly closing the TypeORM connection after each test file runs. If each test module initializes a new connection without cleaning up the old one, TypeORM will throw an error saying a connection is already active.

Fix: Centralize Connection Management with Test Hooks

Instead of creating a new connection in every test file, set up a reusable connection utility and use test lifecycle hooks to handle setup/teardown globally or per file.

First, create a helper file for test connections:

// test/utils/test-db.ts
import { createConnection, getConnection, Connection } from "typeorm";

export async function getTestConnection(): Promise<Connection> {
  try {
    // Reuse existing connection if it exists
    return getConnection();
  } catch {
    // Create a new connection if none exists
    return createConnection({
      type: "postgres", // or your DB type (mysql, sqlite, etc.)
      host: "localhost",
      port: 5432,
      username: "test-user",
      password: "test-pass",
      database: "your-test-db",
      entities: [__dirname + "/../../src/entities/**/*.ts"],
      synchronize: true, // Safely creates tables for your test DB
      dropSchema: false, // We'll handle data clearing separately
    });
  }
}

export async function closeTestConnection(): Promise<void> {
  const connection = getConnection();
  await connection.close();
}

Then, in your test files, use beforeAll and afterAll to manage the connection:

import { getTestConnection, closeTestConnection } from "../utils/test-db";

beforeAll(async () => {
  await getTestConnection();
});

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

// Your tests go here
test("should create and fetch a user", async () => {
  // ... test logic using TypeORM repositories
});

If you're using Jest, add --runInBand to your test script to prevent parallel test runs from conflicting with DB connections:

// package.json
"scripts": {
  "test": "jest --runInBand"
}

Problem 2: Clearing Database Records After Each Test

There are two reliable ways to clear your test DB between tests—choose the one that fits your workflow:

Option 1: Use Transactions (Fastest for Unit Tests)

Wrap each test in a database transaction and roll it back after the test finishes. This is faster than deleting records because transactions don't write to the actual DB until committed.

Add this to your test file (or a global test setup):

import { getConnection, QueryRunner } from "typeorm";

let queryRunner: QueryRunner;

beforeEach(async () => {
  const connection = await getTestConnection();
  queryRunner = connection.createQueryRunner();
  await queryRunner.startTransaction();
});

afterEach(async () => {
  await queryRunner.rollbackTransaction();
  await queryRunner.release();
});

Option 2: Clear All Entity Records

If transactions don't work for your use case (e.g., testing end-to-end flows with external services), you can explicitly delete all records from every entity:

async function clearAllRecords(): Promise<void> {
  const connection = await getTestConnection();
  const entities = connection.entityMetadatas;

  // Disable foreign key checks temporarily (adjust for your DB)
  await connection.query("SET CONSTRAINTS ALL DEFERRED"); // For PostgreSQL
  // Use `SET FOREIGN_KEY_CHECKS = 0;` for MySQL instead

  for (const entity of entities) {
    const repository = connection.getRepository(entity.name);
    await repository.clear();
  }

  // Re-enable foreign key checks
  await connection.query("SET CONSTRAINTS ALL IMMEDIATE"); // PostgreSQL
  // Use `SET FOREIGN_KEY_CHECKS = 1;` for MySQL
}

// Use in afterEach to clear data after every test
afterEach(async () => {
  await clearAllRecords();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:51:51