测试环境中Sequelize未使用指定测试数据库端口问题排查
问题:Sequelize测试环境连接错误数据库端口
使用Sequelize作为ORM、Jest做测试,通过Docker Compose运行开发库(5432端口)和测试库(5433端口)两个PostgreSQL实例。控制台显示环境变量配置值正确,但测试时Sequelize始终使用默认的5432端口,导致连接到开发库而非测试库。
相关配置文件
docker-compose.yml
version: "3.8" services: db: image: postgres environment: POSTGRES_USER: bana_software POSTGRES_PASSWORD: BANASOFTWARE POSTGRES_DB: banasoftware ports: - "5432:5432" volumes: - db_data_dev:/var/lib/postgresql/data db_test: image: postgres environment: POSTGRES_USER: bana_software POSTGRES_PASSWORD: BANASOFTWARE POSTGRES_DB: banasoftware_test ports: - "5433:5432" volumes: - db_data_test:/var/lib/postgresql/data volumes: db_data_dev: db_data_test:
vehicle.test.js
import database from "../config/database"; import request from "supertest"; import app from "../app/app.js"; import { v4 as uuidv4 } from "uuid"; import config from "../helpers/enviroment.js"; describe("Vehicle", () => { beforeAll(async () => { console.log(database.db.config,config) await database.db.sync({ force: true }); await Vehicle.create({ vehicle_id: uuidv4(), available: true }); }); afterAll(async () => { const queryInterface = database.db.getQueryInterface(); const tables = ["Vehicle"]; // 需要清理的表列表 for (const table of tables) { await queryInterface.bulkDelete(table, null, { truncate: true, cascade: true, restartIdentity: true, }); } await database.db.close(); }); describe("GET /vehicles", () => { it("应返回所有车辆", async () => { const res = await request(app).get("/api/vehicles"); expect(res.status).toBe(200); expect(res.body).toBeInstanceOf(Array); expect(res.body.length).toBe(1); }); }); });
控制台输出
console.log(database.db.config)
{ database: 'banasoftware_test', username: 'bana_software', password: 'BANASOFTWARE', host: 'localhost', port: 5432, pool: {}, protocol: 'tcp', native: false, ssl: undefined, replication: false, dialectModule: null, dialectModulePath: null, keepDefaultTimezone: undefined, dialectOptions: undefined }
console.log(config)
{ username: 'bana_software', password: 'BANASOFTWARE', database: 'banasoftware_test', host: 'localhost', port: '5343', dialect: 'postgres' }
.env文件
DB_USER=bana_software DB_PASSWORD=BANASOFTWARE DB_NAME=banasoftware_test DB_HOST=localhost DB_PORT=5343 PORT=3000 NODE_ENV=test
config/database.js
import { Sequelize } from "sequelize"; import config from "../helpers/enviroment.js"; class Database { constructor() { this.db = new Sequelize(config.database, config.username, config.password, { host: config.host, dialect: config.dialect, }); } } export default new Database();
app/app.js
import express from "express"; import cors from "cors"; import { VehicleRouter } from "../routers/vehicle.router.js"; class App { constructor() { this.app = express(); this.middlewares(); this.routers(); } middlewares() { this.app.use(express.json()); this.app.use(express.urlencoded({ extended: true })); this.app.use(cors()); } routers() { const routers = [new VehicleRouter()]; routers.forEach((router) => { this.app.use("/api", router.router); }); } } export default new App().app;
.sequelizerc
import path from "path"; // 导出包含数据库相关文件路径的对象 export default { // 包含数据库种子文件(数据填充脚本)的目录 "seeders-path": path.resolve("src/database", "seeders"), // 包含数据库迁移文件(schema变更脚本)的目录路径 "migrations-path": path.resolve("src/database", "migrations"), // 数据库配置文件路径 config: path.resolve("src/database", "config.js"), };
src/database/config.js
import dotenv from "dotenv"; dotenv.config({ path: `.env.${process.env.NODE_ENV}` }); module.exports = { production: {}, development: { dialect: "postgres", host: process.env.DB_HOST, port: +process.env.DB_PORT, username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, }, test: { dialect: "postgres", host: process.env.DB_HOST, port: +process.env.DB_PORT, username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, }, };
package.json scripts
"scripts": { "dev": "cross-env NODE_ENV=development node src/index.js", "test": "cross-env NODE_ENV=test jest --verbose --runInBand" },
helpers/enviroment.js
import dotenv from "dotenv"; dotenv.config({ path: `.env.${process.env.NODE_ENV}` }); const config = { username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, port: process.env.DB_PORT, dialect: "postgres", }; export default config;
问题分析与修复方案
核心问题1:Sequelize未配置端口参数
在config/database.js中,创建Sequelize实例时未传入port配置项,导致Sequelize使用PostgreSQL默认端口5432,忽略了环境变量中的端口值。
修复:
修改config/database.js,在Sequelize配置对象中添加port参数:
class Database { constructor() { this.db = new Sequelize(config.database, config.username, config.password, { host: config.host, dialect: config.dialect, port: config.port, // 新增此行,传入环境变量中的端口 }); } }
核心问题2:环境变量端口与Docker映射不匹配
.env文件中DB_PORT设置为5343,但Docker Compose中测试库的映射端口是5433:5432,两者不匹配。
修复:
修改.env文件中的DB_PORT为5433:
DB_PORT=5433
额外优化:将端口转为数字类型
环境变量读取的端口是字符串类型,Sequelize建议传入数字类型,修改helpers/enviroment.js中的port字段:
port: +process.env.DB_PORT,
完成以上修改后,测试环境的Sequelize会正确连接到Docker中映射5433端口的测试数据库。
内容的提问来源于stack exchange,提问作者Tomi1368
相关产品推荐
相关产品推荐

