Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeORM with multiple env setups

I want to use a separate database for running tests. So I tried to configure TypeORM for multiple environments (dev and test) but it's not working. It only use the 'dev' configuration.

This is my npm scripts:

"scripts": {
    "start": "NODE_ENV=dev node dist/index.js",
    "test": "NODE_ENV=test mocha --reporter spec --compilers ts:ts-node/register 'test/**/*.test.ts'"
}

If I console.log(process.env.NODE_ENV) I get the correct results ("dev" / "test").

This is my ormconfig.json

[
  {
    "environment": "dev",
    "name": "default",
    "driver": {
      "type": "mysql",
      "host": "localhost",
      "port": 3306,
      "username": "root",
      "password": "",
      "database": "api"
    },
    "entities": [ "dist/model/*.js" ],
    "autoSchemaSync": true
  },
  {
    "environment": "test",
    "name": "default",
    "driver": {
      "type": "mysql",
      "host": "localhost",
      "port": 3306,
      "username": "root",
      "password": "",
      "database": "api_test"
    },
    "entities": [ "dist/model/*.js" ],
    "autoSchemaSync": true
  }
]

I connect with createConnection();. I manually created both databases api and api_test beforehand.

Why is TypeORM not using the "test" configuration when I set NODE_ENV=test?

like image 590
olefrank Avatar asked Jul 22 '17 10:07

olefrank


People also ask

Can you have 2 .ENV files?

One solution is to have multiple . env files which each represent different environments. In practice this means you create a file for each of your environments: .

How do I create a connection in TypeORM?

CreateConnection method is provided by TypeORM to create a new connection. It is defined as below, import { createConnection, Connection } from "typeorm"; const connection = await createConnection({ }); Here, createConnection will use the configuration details specified in the ormconfig.


2 Answers

You could change your ormconfig.json to a js file then do something similar to this:

require('dotenv/config');


const database = {
  development: "dev-db",
  production: 'prod-db',
  test: 'test-db'
}

module.exports = {
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  username: 'ur-username',
  password: 'password',
  database: database[process.env.NODE_ENV],
  entities: ['dist/**/*.entity{.ts,.js}'],
  synchronize: true,
  migrationsTableName: 'migration',
  migrations: ['migration/*.js'],
  cli: {
    migrationsDir: 'migration',
  },
};

Then when running your tests, don't forget to set the appropriate environment. NODE_ENV=test should do.

like image 98
Emmanuel Ndukwe Avatar answered Nov 03 '22 18:11

Emmanuel Ndukwe


I had a similar problem. I got this to work by using different 'name' fields for each connection. For my run-time connection, I kept name=default, and for my test connection I used name=test. So:

[
  {
    "environment": "dev",
    "name": "default",
    "driver": {
      "type": "mysql",
      "host": "localhost",
      "port": 3306,
      "username": "root",
      "password": "",
      "database": "api"
    },
    "entities": [ "dist/model/*.js" ],
    "autoSchemaSync": true
  },
  {
    "environment": "test",
    "name": "test",          //// CHANGED
    "driver": {
      "type": "mysql",
      "host": "localhost",
      "port": 3306,
      "username": "root",
      "password": "",
      "database": "api_test"
    },
    "entities": [ "dist/model/*.js" ],
    "autoSchemaSync": true
  }
]

In my application, I would simply use createConnection(), which would automatically use the connection with name=default.

For my tests, I used typeorm's createConnections() (notice the s). This loads all connections. Once loaded, I would immediately after use getConnection('test'), which would get the test connection. My beforeAll in my tests looked like this in typescript:

  beforeAll(async () => {
    await createConnections();
    getConnection('test');
  });

In javascript, it would probably look something like:

  beforeAll(() => {
    createConnections().then(() => {
        getConnection('test');
    });
  });

Then my tests started to pass. Hope that helps.

like image 40
Blake Avatar answered Nov 03 '22 17:11

Blake