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

如何配置TypeORM使其同时支持应用运行与测试环境的数据库操作

问题根源

你当前报错的核心原因是项目入口未主动调用连接初始化方法,修改后的连接工具不会自动创建default连接,同时原有实现存在重复创建报错、清理逻辑异步等待异常的问题,调整方案如下:

步骤1:优化TypeORM连接工具

增加连接存在性判断、环境适配逻辑,修复清理方法的异步问题:

import { createConnection, getConnection, hasConnection, getConnectionOptions } from 'typeorm';

const connection = {
  async create(overrideConfig: Record<string, any> = {}){
    // 避免重复创建连接报错
    if(hasConnection('default')) {
      return getConnection('default');
    }
    const defaultOptions = await getConnectionOptions();
    return createConnection({
      ...defaultOptions,
      // 按环境自动切换数据库host,测试环境默认使用本地数据库,可自行调整
      host: process.env.NODE_ENV === 'test' ? 'localhost' : 'database_clina',
      ...overrideConfig
    });
  },

  async close(){
    if(hasConnection('default')) {
      await getConnection().close(); 
    }
  },

  async clear(){
    const connection = getConnection();
    const entities = connection.entityMetadatas;
    // 等待所有表清理完成,同时处理外键约束导致的删除失败问题
    await Promise.all(entities.map(async (entity) => {
      const repository = connection.getRepository(entity.name);
      await repository.query(`SET FOREIGN_KEY_CHECKS = 0;`);
      await repository.query(`DELETE FROM ${entity.tableName}`);
      await repository.query(`SET FOREIGN_KEY_CHECKS = 1;`);
    }));
  },
};

export default connection;
步骤2:修改项目入口文件

区分环境初始化连接,测试场景下交由测试用例手动控制连接生命周期:

import "reflect-metadata";
import connection from "./infra/typeorm";
import express from "express";

import { usersRoutes } from "./routes/users.routes";

const app = express();

app.use(express.json());
app.use("/users", usersRoutes);

// 非测试环境自动初始化连接并启动服务
if(process.env.NODE_ENV !== 'test') {
  (async () => {
    try {
      await connection.create();
      app.listen(3000, () => {
        console.log('服务已启动,监听端口3000');
      })
    } catch (err) {
      console.error('数据库连接失败:', err);
      process.exit(1);
    }
  })()
}

export { app };
步骤3:配置环境变量与测试用例
  1. 在package.json中区分不同环境的启动参数:
{
  "scripts": {
    "dev": "NODE_ENV=development ts-node src/index.ts",
    "start": "NODE_ENV=production node dist/index.js",
    "test": "NODE_ENV=test jest"
  }
}
  1. 测试用例示例(以Jest为例):
import { app } from '../src/index';
import connection from '../src/infra/typeorm';
import request from 'supertest';

// 所有测试执行前初始化测试数据库连接
beforeAll(async () => {
  await connection.create({
    // 可传入测试数据库专属配置,比如使用独立的测试库避免污染开发数据
    database: 'your_test_database_name'
  });
})

// 单条测试执行前清空数据库,保证测试用例隔离
beforeEach(async () => {
  await connection.clear();
})

// 所有测试执行完成后关闭连接
afterAll(async () => {
  await connection.close();
})

// 测试用例示例
test('用户创建接口正常返回', async () => {
  const res = await request(app)
    .post('/users')
    .send({ name: '测试用户', email: 'test@example.com' });
  expect(res.statusCode).toBe(201);
})

调整完成后,开发/生产环境启动时会自动创建数据库连接,支持Insomnia接口调用;测试场景下可手动控制连接的创建、清理、关闭逻辑,两端互不冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:12:03