0

I'm trying to test routes in my express app. App.js is a subapp, when it runs it waits for DB connection and then mounts the routes based on the result.

app.js

db.connect() // returns a promise
.then(dbConnection => {
  app.use(routes(dbConnection));
  app.emit('dbConnected'); // DB Connected
}).catch(error => {
  // if db connection fails - return 503 for every request
  console.log(`DB connection failed.`);
  app.use((req, res, next) => {
    const error = new Error('Service unavailable');
    error.statusCode = 503;
    error.name = err.name;
    next(error)
  });  
});

module.exports = app;

I've written the app.test.js to test the routes. I want the tests to wait until the connection is established (because only then the routes are mounted).

app.test.js

before(function (done) {
  app.on('dbConnected', () => done());
});
// tests go here...

The problem is that the 'dbConnected' event is not always caught by the event handler in app.test.js and I get ELIFECYCLE error.

1) "before all" hook: Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

The tests sometimes run correctly, therefore I'm assuming that this is a problem with how I handle the 'dbConnected' event. I'd like to know how to approach this problem properly.

rufus1530
  • 765
  • 4
  • 19
  • Have you tried increasing the timeout ? https://stackoverflow.com/questions/41949895/how-to-set-timeout-on-before-hook-in-mocha – Seblor Jul 16 '18 at 12:52
  • 1
    now I noticed that my before handler is outside of the describe function. Embedding it inside solved the problem :) – rufus1530 Jul 16 '18 at 12:56

1 Answers1

1

It might be a race condition - it's possible that the DB got connected before the test started. In such a case you'll never get the event because it has already fired.

I would check if the DB is connected and only if it isn't I'll wait for the 'dbConnect' event. Something like

before(function (done) {
  if (app.isDbConnected) { // set app.isDbConnected when connected.
    process.nextTick(done)
  } else {
    app.on('dbConnected', () => done());
  }
});
Ariel Steiner
  • 368
  • 3
  • 9