Keep MongoDB connection open while running tests using mocha framework

天涯浪子 提交于 2021-02-10 22:52:30

问题


I'm using something akin to How to properly reuse connection to Mongodb across NodeJs application and modules to keep my mongoDB Connection open.
This requires all the code to go into a MongoDB.connectDB(async (err) => {...} Block.
How would I use this when writing Tests with Mocha.
Do I have to use a separate Connection for every test? Like this?

const MongoDB = require('../src/mongoUtil') // providing access to the mongo database
var events = require('../src/events') // containing all my database Functions

describe('events.js', function () {
  describe('addEvent()', function () {
    it('should return the event, when added succesfully', async function () {
      await MongoDB.connectDB(async (err) => {
        if (err) throw err

        const database = MongoDB.getDB()
        const eventsCollection = database.db().collection('events')

        const event = {
          name: 'test Event',
          members: []
        }

        const result = await events.addEvent(eventsCollection, event)

        MongoDB.disconnectDB()

        if (result.name !== event.name) {
          return new Error('TODO')
        }
      })
    })
  })
})

For this example to work properly I probably also have to manually set the test to done, if I understood the mocha website correctly?
Can I have just one connection?

mongoUtil.js

const MongoClient = require('mongodb').MongoClient
const uri = 'mongodb://localhost:27017/testing'

let _db

const connectDB = async (callback) => {
  try {
    MongoClient.connect(uri, { useNewUrlParser: true }, (err, db) => {
      _db = db
      return callback(err)
    })
  } catch (e) {
    throw e
  }
}

const getDB = () => _db

const disconnectDB = () => _db.close()

module.exports = { connectDB, getDB, disconnectDB }

events.js

const addEvent = async (collection, event) => {
  try {
    const exists = await collection.findOne({ 'name': event.name })
    if (exists) {
      return false
    } else {
      const results = await collection.insertOne(event)
      return results.ops[0]
    }
  } catch (e) {
    throw e
  }
}
module.exports = { addEvent }

回答1:


You don't need to put everything inside MongoDB.connectDB({...}). This is called callback hell which should be avoided when possible. mongoUtil is inconvenient wrapper that doesn't make MongoDB API simpler or easier to use.

await MongoDB.connectDB(async (err) => { ... is a mistake. Putting async function as a callback is not enough and will result in improper control flow.

MongoClient.connect uses error-first callbacks, so it can be used with done to pass errors to test suite:

let db;

beforeEach(done => {
  MongoClient.connect(uri, { useNewUrlParser: true }, (err, _db) => {
    db = _db;
    done(err);
  });
});

connectDB incorrectly promisifies MongoClient.connect. There's no need for one-time callbacks when promises and async..await are in use. It could be:

const connectDB = () => {
  return new Promise((resolve, reject) => {
    MongoClient.connect(uri, { useNewUrlParser: true }, (err, db) => {
      if (err) reject(err);
      else resolve(db);
    });
  });
};

But the fact is that mongodb supports promises natively when callback argument is omitted. mongoUtil needs only one helper function, connectDB:

const connectDB = () => MongoClient.connect(uri, { useNewUrlParser: true });

Which can be used with Mocha seamlessly since it supports promises:

let db;

beforeEach(async () => {
  db = await connectDB();
});

afterEach(() => db.close());

close is asynchronous and returns a promise, too.



来源:https://stackoverflow.com/questions/51993399/keep-mongodb-connection-open-while-running-tests-using-mocha-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!