I have a REST app written in NodeJS running on Heroku. I have my .env file setup for local development and works fine whenever I run foreman to serve my app locally. The app also runs fine when I deploy it to my heroku server.
I am trying to write unit tests for my app with Mocha/Supertest/should/assert. When I run my app through Mocha, it doesn't load up the .env file to get my environment variables – in my case, the URL for the PSQL database. As a result, all my tests that involve DB I/O timeout.
I've been scouring the Internet for a solution but I can't seem to find anything helpful.
Here is some sample code:
app.js:
var application_root = __dirname,
express = require("express"),
port = process.env.PORT || 4482;
pg = require('pg').native,
client = new pg.Client(process.env.DATABASE_URL);
// Connect To DB
client.connect();
(...)
app.get('/api', function (req, res) {
res.send('PS API is running');
});
app.get('/', function (req, res) {
res.send('PS API is running');
});
(...)
// Read Users
app.get('/users', function (req,res) {
user.readUsers(res,client);
});
(...)
// Launch server
console.log('Listening on port: '+ port);
app.listen(port);
module.exports = app;
userTest.js
var request = require('supertest');
var assert = require('assert');
var app = require('app.js');
var should = require('should');
describe('Get /', function(){
it('should respond OK',function(done){
request(app)
.get('/')
.end(function(err, res){
res.status.should.equal(200);
done(err);
});
});
});
describe('Get /api', function(){
it('should respond OK',function(done){
request(app)
.get('/api')
.end(function(err, res){
res.status.should.equal(200);
done(err);
});
});
});
// Getting All Users
describe('Get /users', function(){
it('should respond OK',function(done){
request(app)
.get('/users')
.end(function(err, res){
res.status.should.equal(200);
done(err);
});
});
});
.env
== LOCAL DB ==
DATABASE_URL=MY_DB_URL
HEROKU_POSTGRESQL_GOLD_URL=MY_DB_URL
PATH=bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin
And the output I get from running mocha test
Listening on port: 4482
․․Getting all users
․
2 passing (2 seconds)
1 failing
1) Get /users should respond OK:
Error: timeout of 2000ms exceeded
at Object.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:165:14)
at Timer.list.ontimeout (timers.js:101:19)
When I replace the process.env.DATABASE_URL
with my hardcoded PSQL local URL, the tests all pass. So it's clear that the .env file is not being read by mocha.
I have also tried passing env vars to Mocha with little success. Does anyone know of a proper way to have Mocha read in my environment vars from the .env file?
The foreman gem (written by a Heroku engineer, to make it easy to use .env
files and Procfiles
in development as you would on Heroku production) has a command just for this purpose: run
.
foreman run npm test
<-- or however you trigger your tests.
Alternatively, on my current project here's what we do:
export
format. So, yes, export DATABASE_URL=MY_DB_URL
. The format is a bit different, but that's an annoyance we're OK with-include test.env test: npm test
When we want to run the tests for our project we just make test
. Make will load up the test.env
file, assign all the environmental variables, then run npm test
for us.
I'm not entirely sure, but I don't think you can make mocha read your .env file. That appears to be specific to foreman. If your environment variable definitions are plain KEY=VALUE, then I believe something as simple as env $(cat .env) mocha
would do. Otherwise, you may have to do some preprocessing first using sed/perl/etc.
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