使用Mocha框架运行测试时保持MongoDB连接打开

时间:2018-08-23 19:55:35

标签: javascript node.js mongodb mocha

我正在使用类似于How to properly reuse connection to Mongodb across NodeJs application and modules的方式来保持我的mongoDB连接打开。
这要求所有代码都放入MongoDB.connectDB(async (err) => {...}块中。
用Mocha编写测试时,我将如何使用它。
每次测试都必须使用单独的连接吗?像这样?

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')
        }
      })
    })
  })
})

为了使此示例正常运行,如果我正确理解了摩卡网站,我可能还必须手动将测试设置为完成?
我可以只建立一个连接吗?

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 个答案:

答案 0 :(得分:1)

您不需要将所有内容都放在MongoDB.connectDB({...})中。这称为回调地狱,应尽可能避免。 mongoUtil是一种不方便的包装器,不会使MongoDB API变得更简单或更易于使用。

await MongoDB.connectDB(async (err) => { ...是一个错误。将async函数用作回调是不够的,并且会导致不正确的控制流。

MongoClient.connect使用错误优先回调,因此可以与done一起使用,以将错误传递给测试套件:

let db;

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

connectDB错误地承诺了MongoClient.connect。当使用promise和async..await时,不需要一次回调。可能是:

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

但是事实是,当省略回调参数时,mongodb会原生支持promise。 mongoUtil仅需要一个辅助功能,connectDB

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

哪些可以与Mocha无缝配合使用,因为它支持promises:

let db;

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

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

close是异步的,并且也返回一个Promise。