Environment variables not found during Mocha unit test Node.js - javascript

I am trying to run a mocha unit test but one of the modules used by the module I am testing on requires environment variables such as process.env.CLIENT_ID through dotenv. When I run my Mocha test, these environment variables are not found. How can I can include environment variables from a .env file in my mocha unit tests?
test.js:
var messenger = require(__dirname + "/../routes/messenger.js");
var assert = require("assert")
describe("Return Hello", function(){
it('Should return hello',function(done){
messenger.testFunction(function(value){
assert(value === "Hello", 'Should return Hello')
done()
})
})
})
Section of file that contains the problem that goes through unit test:
var express = require("express")
var router = express.Router();
require('dotenv').config()
var plaid = require('plaid');
var mysql = require('mysql');
var fs = require("fs");
const plaidClient = new plaid.Client(
process.env.PLAID_CLIENT_ID, // these are all not found
process.env.PLAID_SECRET,
process.env.PLAID_PUBLIC_KEY,
plaid.environments.sandbox);

to me the most elegant way of setting your env before the tests is inside package.json.
Here is an example to adapt to your own npm test command:
"scripts": {
"test": "mocha -r dotenv/config"
}
The main idea is to add the -r dotenv/config.
The method works as well with dotenv-flow, do not forget to add NODE_ENV=test at the beginning of the command.
It works as well with nodemon.

I found the solution. I had to link the dotenv config explicitly to the location to the .env file by adding the path: options of the .config() method.
Example:
var envPath = __dirname + "/../.env"
require('dotenv').config({path:envPath})
// ^ this was incorrect
var express = require("express")
var router = express.Router();
var plaid = require('plaid');
var mysql = require('mysql');
var fs = require("fs");
const plaidClient = new plaid.Client(
process.env.PLAID_CLIENT_ID,
process.env.PLAID_SECRET,
process.env.PLAID_PUBLIC_KEY,
plaid.environments.sandbox);

The below thing worked for me ;)
"scripts": {
"test": "set DOTENV_CONFIG_PATH=test.env && mocha -r dotenv/config ",
}

Related

How can I choose the NODE_ENV in windows terminal without using npm?

I'm studying a NodeJs course, the main purpose of this course is to learn NodeJS without using npm, so we reached a stage where we defined our environment variable for staging and production, and I couldn't switch between the NODE_ENV from cmd terminal, we have a config.js file that exports the environment, the index.js imports them and based on the NODE_ENV asked for, it give it to you .
-so this is the config.js script :
/*
**** Creating and exporting config variables
*/
//
var environments = {};
//
environments.staging ={
'port' : 3000,
'envName' : 'staging',
}
environments.production ={
'port' : 5000,
'envName' : 'production',
}
//
var currentEnvironment = typeof(process.env.NODE_ENV) == 'string' ? process.env.NODE_ENV.toLowerCase() :'';
//
var environmentToExport = typeof(environments[currentEnvironment]) == 'object' ? environments[currentEnvironment] : environments.staging;
//
module.exports = environmentToExport;
and the Index.js script is this :
var http = require('http');
var url = require('url');
var stringDecoder = require('string_decoder').StringDecoder;
var config = require('./config');
var server = http.createServer((req,res)=>{ to many lines i coudln't paste them });
server.listen(config.port,()=>{
console.log("Server listening on port NÂș : "+config.port+" in "+config.envName+" environment ");
});
So how can I choose the NODE_ENV from terminal ?
As the NODE_ENV is an Environment Variable, you can change this option on the terminal session with the command set (on CMD):
set NODE_ENV=production
node index.js

Why would gulp.watch not run on a windows computer when the same code executes on other windows computers?

I'm helping a remote coworker to setup with gulp on their Windows 10 computer, and have ran into an issue where the watch function in gulp simply will not work.
Other gulp functionality works well, but watch in particular just hangs without any error to the screen.
To ensure I'm not missing anything in my code, I made a simple test gulpfile to be sure that this wasn't due to some other reason.
gulpfile.js
var gulp = require("gulp");
var fs = require('fs');
var compareToPreviousRead = require("./fileReaderTest.js");
gulp.task("watch", function(){
return gulp.watch("Test.txt", async function(){
var diff = await compareToPreviousRead();
console.log(`Diff: "${diff}", Time: "${new Date().toGMTString()}"`);
Promise.resolve(true);
});
});
fileReaderTest.js
var fs = require('fs');
var readTestFile = () => new Promise(resolve => {
fs.readFile('Test.txt', 'utf8', (err, contents) => resolve(contents));
});
var originalValue = "";
var compareToPreviousRead = () => new Promise(resolve => {
readTestFile().then(updatedValue => {
var diff = updatedValue.replace(originalValue, "");
originalValue = updatedValue;
resolve(diff);
});
});
module.exports = compareToPreviousRead
I also included a few PowerShell Scripts to install and run the app from the same directory.
Someone could also just manually edit a file called "Test.txt" in the same directory (only appending to the file) and the gulp task would work correctly.
WriteToFileEverySecond.ps1
param ($testFileLocation)
Start-Sleep -Seconds 1
$i = 0
for ($i=0; $i -lt 10; $i++){
[System.IO.File]::AppendAllText($testFileLocation, "$i--", [System.Text.Encoding]::Ascii)
Start-Sleep -Seconds 1
}
TestGulpWatch.ps1
$currDir = $PSScriptRoot
cd $currDir
npm install --silent
Remove-Item "$currDir/Test.txt" -ErrorAction SilentlyContinue > $null
New-Item "Test.txt" -ItemType File > $null
$job1 = Start-Job -ScriptBlock {
param($currDir)
cd $currDir
gulp watch --silent
} -ArgumentList $currDir
Start-Sleep -Seconds 1
$job2 = Start-Job -FilePath "$currDir/WriteToFileEverySecond.ps1" -ArgumentList "$currDir/Test.txt"
while ($job1.HasMoreData -and $job2.HasMoreData) {
$job1,$job2 | Receive-Job
}
$job1,$job2 | Stop-Job
$job1,$job2 | Remove-Job
pause
They are using the following versions:
npm: 6.13.1
gulp cli version: 2.2.0
gulp repo version: 4.0.2

DOTENV not reading variables properly

This is my file:
postgresU="myuser"
postgresP="mypass"
postgresH="myhost"
postgresDB="mydb"
postgresC="postgres://${postgresU}:{$postgresP}#{$postgresH}:5432/${postgresDB}"
In my nodejs app,
require('dotenv').config();
var connectionString = process.env.postgresC;
console.log("Connection String:",connectionString);
This prints:
Connection String: "postgres://${postgresU}:${postgresP}#${postgresH}:5432/${postgresDB}"
What am I doing wrong?
You can use a package like dotenv-expand if you want to expand variables in .evn files.
Once installed (with npm or yarn) you can simply use a .env file with:
postgresU="myuser"
postgresP="mypass"
postgresH="myhost"
postgresDB="mydb"
postgresC="postgres://${postgresU}:${postgresP}#${postgresH}:5432/${postgresDB}"
and then process it with:
const dotenv= require('dotenv')
const dotenvExpand = require('dotenv-expand')
let myEnv = dotenv.config()
dotenvExpand(myEnv)
let connectionString = process.env.postgresC;
console.log(connectionString)
postgres://myuser:mypass#myhost:5432/mydb

Unable to read config.json file in node.js

I am writing a unit test case for the , question is mentioned in the link How to stub/mock submodules of a require of nodejs using sinon
when I include a require
const index=require('./index.js');
It has a library require inside it
const library= require('./library.js');
the library.js file has a require which reads config.json file(this config file is also required inside above index.js) as below
const readConfig = require('read-config');
const config = readConfig('./config.json');
I have tried many ways as suggested in the above link but I am failing
const stubs = {
'./library': function (response) {
assert.equal(some, null);
return 'Some ' + argument;
},
'../library1.js': {
function(paths, opts){
var config='./config.json'
return config;
}
},
}
const index=proxyquire('./index.js',stubs)
When I run my unit test case I am still getting the below error
throw configNotFound(configPath);
^
ReadConfigError: Config file not found: ./config.json
I would like to know which part of the code I am missing badly that the code throws the error
I am trying to edit the index.js and all the related files where config is read with the below code
var path = require('path');
var pathToJson = path.resolve(__dirname, '../config.json');
// Load config
var config = fs.readFile(pathToJson , 'utf8', function (err, data) {
if (err) throw err;
config = JSON.parse(data);
});
Here challenge is that I cannot change the node code
You problem is likely to be path resolution. If ./config.json is relative to where you are running Node from (process.cwd()), then it'll work. If it's relative to your library module, then you can do something like:
// Works for JS and JSON
const configPath = require.resolve('./config.json');
// Works in general
const configPath = require('path').join(__dirname, 'config.json');
// Then
const readConfig = require('read-config');
const config = readConfig(configPath);
It's difficult to say if this is the case without knowing more about your project layout and how you're starting your app.

Why does running Mocha with Node.js work the first time, but not the second?

I have a testing app that has a UI that allows users to select certain tests and run those tests by clicking a button with Mocha. For some reason, the first time, the tests run and I get the passing results (2 passing or whatever). Any subsequent click of the button even with all the same values selected will run Mocha, but it runs 0 tests. So, it returns 0 passing. Here is the code that runs when the AJAX POST is made:
var Mocha = require('mocha'),
fs = require('fs'),
path = require('path');
var mocha = new Mocha({
reporter: 'list'
});
fs.readdirSync('node_modules/selenium-webdriver/nb_tests/').filter(function (file) {
return file.substr(-3) === '.js';
}).forEach(function (file) {
mocha.loadFile(path.join('node_modules/selenium-webdriver/nb_tests/', file));
});
// Now, you can run the tests.
mocha.run(function (failures) {
process.on('exit', function () {
process.exit(failures);
});
});
Btw, when I console.log(mocha) right before running the tests they are identical on all requests. Any ideas what might be causing the issue?
Figured this out...it seems that Mocha didn't like me creating a new instance for each POST. The code above was all contained in the route handler. So, here is what I did:
var Mocha = require('mocha');
var path = require('path');
var fs = require('fs');
var mocha = new Mocha({
reporter: 'list'
});
app.post('/runtest', function (req, res) {
fs.readdirSync('node_modules/selenium-webdriver/nb_tests/').filter(function (file) {
return file.substr(-3) === '.js';
}).forEach(function (file) {
mocha.addFile(path.join('node_modules/selenium-webdriver/nb_tests/', file));
});
mocha.run();
});

Categories