Reputation: 343
I am a newbie to the JavaScript ecosystem. I am trying to write couple of API tests for my REST APIs using Mocha/Chai. My requirement is that I have to cleanup my database before running each test cases. So, I wrote the following code in a file called dbCleanup.js
var config = require("config.json");
const pg = require('pg');
var connectionString = config.pgConnectionString
console.log("DB Connection String: ", connectionString)
function dbCleanup() {
var dbTables = ["projects", "employees"];
var pgClient = new pg.Client(connectionString);
var promise = new Promise(function (resolve, reject) {
pg.connect(connectionString, (err, pgClient, done) => {
if (err) {
done();
console.log(err);
reject();
}
for (i = 0; i < dbTables.length; i++) {
query = "TRUNCATE " + dbTables[i] + " CASCADE;"
pgClient.query(query, function (err, res) {
if (err) {
done();
console.error('error running query', err);
reject();
}
resolve();
});
}
});
});
pgClient.end()
return promise;
}
exports.dbCleanup = dbCleanup;
I have another file called globalBefore.js where I have the following code:
var dbCleanup = require('./dbCleanup.js').dbCleanup;
function _beforeClean(done) {
try {
dbCleanup()
.then(done)
} catch (err) {
console.error(err);
}
}
exports.beforeCleanup = _beforeClean;
Now in my Mocha test.js file, I try to call the database cleanup function as follows:
var request = require("request");
var rp = require("request-promise");
var config = require("../config.json");
var expect = require('chai').expect;
var data = require("./data.json");
var globalBefore = require("../globalBefore.js");
describe("POST /employees/", function () {
console.log("clearing db tables...")
before(globalBefore.beforeCleanup, function (done) {
done();
});
beforeEach(function (done) {
... do some business logic related work here ...
});
it.only('Try create an employee', function (done) {
... API call to create an employee and use Chai assertions to validate ...
});
});
The problem I am facing is, Mocha goes ahead with running my tests even before the dbCleanup() function completes. This causes my DB to go kaput and I encounter undesired behavior.
Can anyone from the SO community please help? I tried various options I could find in the web, but not able to fix the issue. As shown in the code fragment, I hoped that using a Promise should have solved the problem
To be more generic, how do I enforce the instructions inside a before clause to complete before Mocha runs the it clauses for the tests?
Thanks!
Upvotes: 0
Views: 940
Reputation:
You are using before
the wrong way. Try this instead:
before(function (done) {
globalBefore.beforeCleanup(done);
});
or
before(globalBefore.beforeCleanup);
And in globalBefore.js
:
var dbCleanup = require('./dbCleanup.js').dbCleanup;
function _beforeClean(done) {
dbCleanup().then(done).catch(done);
}
exports.beforeCleanup = _beforeClean;
EXAMPLE (I only changed dbCleanup.js to use a another promise)
dbCleanup.js
function dbCleanup() {
return new Promise(function (resolve, reject) {
setTimeout(resolve, 2000);
});
}
exports.dbCleanup = dbCleanup;
globalBefore.js
var dbCleanup = require('./dbCleanup.js').dbCleanup;
function _beforeClean(done) {
dbCleanup().then(done).catch(done);
}
exports.beforeCleanup = _beforeClean;
index.js
var globalBefore = require("../globalBefore.js");
describe("POST /employees/", function () {
this.timeout(5000); // because the promise take 2000ms
console.log("clearing db tables...")
before(function (done) {
console.log('before calling beforeCleanup');
globalBefore.beforeCleanup(function () {
console.log('after calling beforeCleanup');
done(); // done cleaning db
});
});
/* Without the console.logs
console.log("clearing db tables...");
before(globalBefore.beforeCleanup)
*/
beforeEach(function (done) {
// ... do some business logic related work here ...
console.log('beforeEach');
done();
});
it.only('Try create an employee', function (done) {
// ... API call to create an employee and use Chai assertions to validate ...
console.log('it');
done();
});
});
OUTPUT
clearing db tables...
POST /employees/
before calling beforeCleanup
after calling beforeCleanup
beforeEach
it
√ Try create an employee
1 passing (2s)
Upvotes: 1