Shri
Shri

Reputation: 751

NodeJS change MongoDB database name on testing environment

I have this piece of code to connect to MongoDB:

MongoClient.connect(
      process.env.MONGO_HOST,
      { useUnifiedTopology: true },
      function (err, client) {
        _db = client.db(process.env.DB_NAME);
        _client = client;
        return callback(err);
      }
    );

I am using mocha and chai to test my application. The problem is since the db name comes from process.env.DB_NAME, the same database is modified while running npm test. Is there a way to change the db name based on the command given to start the server so that the tests can modify a seperate db of it's own?

Upvotes: 1

Views: 1701

Answers (3)

EmirDev
EmirDev

Reputation: 87

If I understand you correctly, you want to have two separate environments on your local machine: one for development (with its own database) and one for testing (with its own database).

This is how I would do things.

  • I would keep the environment variables as non-checked in files (since they oftentimes contain private keys and such). (So, they are added to .gitignore file, especially if it is in a publicly accessible repo). This has also the benefit of having fixed .env variables for your machine. (Otherwise, if you check in the files, other developers who have different values, they will have to modify these variables at each pull from master.

  • You are using the dotenv package as far as I understand. You can create .env files to be parsed by this package. For example, .env.dev and .env.test

  • In your package.json, you modify your dev and test scripts to set node to a specific environment. For example,

    "scripts": {
    "dev": "NODE_ENV=dev node ./server.js",
    "test": "NODE_ENV=test mocha ./test/test.js",
    },

  • As final step, in the relevant part of the application as early as possible (for example, during the server bootup in server.js), you do

    require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` }).

  • Now, process.env is loaded with your environment variables from the correct .env file.

Upvotes: 1

james_womack
james_womack

Reputation: 10306

Doing something like process.env.MONGO_HOST='foo'; inside a module is a code smell—don't do it.

In the most basic of Node project setups, you can modify your "test" script so that tets/local environment variables are prepended to your test runner & start scripts. Example:

package.json

{
  "name": "@jameswomack/npm-config-example",
  "scripts": {
    "test": "$npm_package_config_dblocal mocha ./src/*.test.js",
    "start-server": "node ./src/index.js",
    "start:local": "$npm_package_config_dblocal npm run start-server",
    "start:prod": "$npm_package_config_dbprod npm run start-server"
  },
  "config": {
    "dbprod": "env MONGO_HOST=https://fu.manchu DB_NAME=1337;",
    "dblocal": "env MONGO_HOST=localhost DB_NAME=local;"
  },
  "devDependencies": {
    "mocha": "8.1.3"
  }
}

See example within example repo here

Upvotes: 0

jishi
jishi

Reputation: 24624

What I usually do if I want to my test configuration to be checked into repo (because it isn't dependent on how your dev environment is configured), I add a folder and a test file that I know will be loaded first:

tests
 \ 00-init
   \ 00-init.js

Which just contains

process.env.MONGO_HOST = 'localhost';
process.env.DB_NAME = 'test';

Of course, this doesn't really work if different devs are using different hosts and database names for testing, then they should supply their own ENV variables when running the tests.

If you use a test runner in your IDE, you can normally specify which ENV variables that you want to set, otherwise you can specify them for your terminal, or directly when you are invoking your command line (for unix shell type terminals):

MONGO_HOST=localhost DB_NAME=test npm test

In your case, where you are using dotenv, you can still override any ENV variables like this because dotenv won't overwrite an ENV variable that already exists.

Upvotes: 1

Related Questions