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

Jest中实现所有测试文件仅初始化一次服务与数据库连接

解决多测试文件下数据库全局初始化与服务器共享问题

问题背景

项目包含多个测试文件,每个文件都重复实现beforeAll/afterAll来启动服务器、初始化数据库及终止连接。已通过测试环境不指定端口解决端口占用,但多文件运行时会触发数据库UniqueConstraintError,需要实现服务器与数据库的全局一次性初始化,同时保证测试用例能正常访问server调用API。

解决方案步骤

1. 配置全局初始化与清理脚本

利用测试框架(以Jest为例)的全局Setup/Teardown机制,实现仅执行一次的初始化和清理逻辑:

全局初始化脚本(tests/globalSetup.js)

const db = require('../service/pg');
const createServer = require('../service/server');

module.exports = async () => {
  // 初始化数据库连接并同步模型
  const sequelize = await db.init();
  // 创建并启动Hapi服务器
  const server = await createServer();
  await server.start();

  // 将实例挂载到全局对象,供所有测试文件访问
  global.testServer = server;
  global.sequelize = sequelize;
};

全局清理脚本(tests/globalTeardown.js)

module.exports = async () => {
  // 停止服务器
  await global.testServer.stop();
  // 清理数据库并关闭连接
  await global.sequelize.drop();
  await global.sequelize.close();
};

更新Jest配置(jest.config.js)

module.exports = {
  globalSetup: './tests/globalSetup.js',
  globalTeardown: './tests/globalTeardown.js',
  // 保留其他原有配置
};

2. 改造数据库连接为单例模式

避免多次初始化数据库连接,在sequelize.js中实现单例:

const { Sequelize } = require('sequelize');
const env = require('./env'); // 替换为你的环境变量配置路径

let user_db;

// 单例模式确保仅创建一个数据库连接实例
function getSequelizeInstance() {
  if (!user_db) {
    user_db = new Sequelize(
      env.dbName,
      env.user,
      env.password,
      {
        host: env.host,
        port: env.port,
        dialect: 'postgres',
        logging: false,
      }
    );
    // 在此处添加模型定义...
  }
  return user_db;
}

module.exports = getSequelizeInstance();

3. 简化数据库初始化逻辑

修改db.js,确保模型同步仅在全局初始化时执行一次:

const sequelize = require('./sequelize');

async function init() {
  await sequelize.sync();
  return sequelize;
}

module.exports = { init };

4. 简化测试文件代码

移除测试文件中重复的beforeAll/afterAll,直接使用全局挂载的server实例:

describe('testing...', () => {
  test('one + one = 2', async () => {
    const options = {
      method: 'POST',
      url: '/math',  
    };
    // 使用全局的testServer实例发起请求
    const res = await global.testServer.inject(options);
    expect(1).toEqual(1);   
  });
});

关键说明

  • 全局脚本确保服务器和数据库仅初始化/清理一次,彻底避免重复操作导致的唯一约束冲突。
  • 单例模式的数据库连接防止多文件重复创建连接实例。
  • 测试文件直接复用全局server,无需重复启动,提升测试效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:27:22