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?
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: .
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With