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:
- 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 toapp.locals.db
.
MongoClient.connect(${productionUrl}, (err, db) => {
if (err) throw err;
app.locals.db = db;
server.listen(port);
});
-
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 themakeApp()
function (as is done in the supertest instructions), assignapp.locals.db
to the database instance that was returned fromawait dbClient.connect(await MongoDBServer.getConnectionString());
(from the MongoDB testing instructions). -
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.