rufus1530
rufus1530

Reputation: 795

Wait for DB connection before running tests - event issue

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.

Upvotes: 0

Views: 1638

Answers (1)

Ariel Steiner
Ariel Steiner

Reputation: 418

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());
  }
});

Upvotes: 1

Related Questions