Despite my (supposedly) simple ask (“How can I use one MongoDB connection for unit testing and one for integration tests?”), finding a solution to the problem proved fiendishly difficult and deserving of a writeup.

Background

To help put this problem into perspective, it’s helpful to know about the general setup I’m using. As the title indicates, I’m using Express with MongoDB to save data after it’s uploaded to the server. Additionally, I’m using Ava for testing my application (including endpoint testing with supertest), and wanted to get started using Mongomem with Ava’s recipe for isolated MongoDB tests.

The problem arose in that I need to establish one DB connection for when the app is running normally, and one for when unit tests are running. Since the unit tests are run indepdently of the rest of the Express server code (i.e. they’re imported individually into Ava tests and have no knowledge of the rest of my Express setup), I needed a solution in which any route could have a way to communicate with MongoDB without having to setup the connection itself.

Solution

After trying various imports/ exports/ passing parameters/ etc., I found a much simpler solution:

  1. Add the “main” DB connection in Express’s www.js file. Right before the server is told to listen on a certain port, setup the Mongo connection and pass the connection to app.locals.db.
MongoClient.connect(${productionUrl}, (err, db) => {
  if (err) throw err;
  app.locals.db = db;
  server.listen(port);
});
  1. Follow Ava’s instructions for endpoint testing with supertest, but combine them with the instructions for MongoDB testing with Mongomem. Right before returning app from the makeApp() function (as is done in the supertest instructions), assign app.locals.db to the database instance that was returned from await dbClient.connect(await MongoDBServer.getConnectionString()); (from the MongoDB testing instructions).

  2. Then, the routes will have access to the DB connection via req.app.locals.db and can perform database operations without caring about what database they’re using.

Conclusion

Hope this helped! It’s been writen up mostly for my own benefit; I’ve spent way too much time trying to architect the best solution to this problem that I wanted to write down what I consider to be the best solution.