在使用 mocha 框架进行 运行 测试时保持 MongoDB 连接打开
Keep MongoDB connection open while running tests using mocha framework
我正在使用类似于 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')
}
})
})
})
})
如果我正确理解了 mocha 网站,为了让这个例子正常工作,我可能还必须手动将测试设置为完成?
我可以只有一个连接吗?
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 }
您不需要将所有内容都放在 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
。当使用 promises 和 async..await
时,不需要一次性回调。可能是:
const connectDB = () => {
return new Promise((resolve, reject) => {
MongoClient.connect(uri, { useNewUrlParser: true }, (err, db) => {
if (err) reject(err);
else resolve(db);
});
});
};
但事实是 mongodb
在省略回调参数时原生支持 promises。 mongoUtil
只需要一个辅助函数,connectDB
:
const connectDB = () => MongoClient.connect(uri, { useNewUrlParser: true });
可以与 Mocha 无缝使用,因为它支持 promise:
let db;
beforeEach(async () => {
db = await connectDB();
});
afterEach(() => db.close());
close
是异步的,returns 也是一个承诺。
我正在使用类似于 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')
}
})
})
})
})
如果我正确理解了 mocha 网站,为了让这个例子正常工作,我可能还必须手动将测试设置为完成?
我可以只有一个连接吗?
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 }
您不需要将所有内容都放在 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
。当使用 promises 和 async..await
时,不需要一次性回调。可能是:
const connectDB = () => {
return new Promise((resolve, reject) => {
MongoClient.connect(uri, { useNewUrlParser: true }, (err, db) => {
if (err) reject(err);
else resolve(db);
});
});
};
但事实是 mongodb
在省略回调参数时原生支持 promises。 mongoUtil
只需要一个辅助函数,connectDB
:
const connectDB = () => MongoClient.connect(uri, { useNewUrlParser: true });
可以与 Mocha 无缝使用,因为它支持 promise:
let db;
beforeEach(async () => {
db = await connectDB();
});
afterEach(() => db.close());
close
是异步的,returns 也是一个承诺。