Search code examples
node.jsexpressdocker-composejestjssequelize.js

Sequelize in test files doesnt get test environment


I´m using sequelize as ORM and jest for testing.

Im running two databases currently with docker compose (test and development). Environment variables are correct in console.log. For one rease Database is using the correct database name but using the incorrect port.

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:

my test file is accessing to db not to db_test. Cause is using port 5432 instead 5433

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"]; // Lista de tablas a limpiar

    for (const table of tables) {
      await queryInterface.bulkDelete(table, null, {
        truncate: true,
        cascade: true,
        restartIdentity: true,
      });
    }
    await database.db.close();
  });

  describe("GET /vehicles", () => {
    it("Should have all vehicles", 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(db.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.file:

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";
// Exporting an object containing paths for database-related files
export default {
  // directory containing database seeders (data population scripts)
  "seeders-path": path.resolve("src/database", "seeders"),
  // Path to the directory containing database migrations (schema change scripts)
  "migrations-path": path.resolve("src/database", "migrations"),
  // Database configuration s
  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,
  },
};

scripts:

"scripts": {
    "dev": "cross-env NODE_ENV=development node src/index.js",
    "test": "cross-env NODE_ENV=test jest --verbose --runInBand"
  },

helpers/enviroments.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;

environmets


Solution

  • https://github.com/FranklinThaker/NodeJs-Sequelize-Express-Jest-CICD-BoilerPlate/blob/970b51d55979f237ffde31f1459d64eb16f46812/package.json#L9

    This might be helpful. Also make sure correct paths are set in .sequelizerc file. This JEST test is working for me with NODE_ENV=test.