我正在使用 jasmine-node 对我的 nodejs 函数运行测试。作为 nodejs 和 mongodb 的新手,我遇到的第一件事是测试一些数据库调用,但由于 nodejs 的异步特性,我立即陷入困境。
我想做的是:
1)添加一个add
函数来将新条目添加到一个 mongodb 表中
2) 从该函数接收状态字符串以验证操作的状态
以下是我的规范的代码。在beforeEach
通话中,我初始化了数据库。正如您在实现中看到的那样,它只实例化一次,因为有一个条件询问它是否已经存在。
var mongo = require('../mongo.js');
describe('mongo', function() {
// generate a random number in order to test if the written item and the retrieved result match
var randomNumber = Math.random();
var item = {
'cities': {
'london': randomNumber
}
};
beforeEach(function() {
mongo.init();
waitsFor(function() {
return mongo.getCollection();
}, "should init the database", 10000);
});
it('should return "added" after adding an item to the database', function() {
var result;
waitsFor(function() {
result = mongo.add(item);
// the result value here is always undefined,
// due to the problem i'm having in my implementation
return result !== undefined;
}, "adding an item to the database", 10000);
runs(function() {
expect(result).toEqual('added');
});
});
});
现在,对于每个数据库查询,我可以定义一个回调函数,当查询成功运行时执行。我不知道如何实现是将 mongodb 回调的结果返回规范。
这是数据库功能的当前实现:
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db;
var server = new Server('localhost', 27017, {auto_reconnect: true});
var db = new Db('exampleDb', server);
var collection = false;
// initialize database
var init = function() {
if (collection === false) {
db.open(dbOpenHandler);
}
};
var dbOpenHandler = function(err, db) {
db.collection('myCollection', dbCollectionHandler);
};
var dbCollectionHandler = function(err, coll) {
collection = coll;
};
/** returns the current db collection's status
* @return object db collection
*/
var getCollection = function() {
return collection !== false;
};
/** Add a new item to the database
* @param object item to be added
* @return string status code
*/
var add = function(item) {
var result = collection.insert( item, {safe: true}, function(err) {
// !! PROBLEM !!
// this return call returns the string back to the callee
// question: how would I return this as the add function's return value
return 'added';
});
};
// module's export functions
exports.init = init;
exports.getCollection = getCollection;
exports.add = add;
我也对如何在 mongodb 中测试数据库调用的其他方法持开放态度。我已经阅读了很多关于这个主题的文章,但没有一篇涵盖我的特殊情况。
解决方案
最后,在 JohnnyHK 的回答的帮助下,我设法通过回调使其工作。查看以下测试用例以了解我所做的事情:
it('should create a new item', function() {
var response;
mongo.add(item, function( err, result) {
// set result to a local variable
response = result;
});
// wait for async call to be finished
waitsFor(function() {
return response !== undefined;
}, 'should return a status that is not undefined', 1000);
// run the assertion after response has been set
runs(function() {
expect(response).toEqual('added');
});
)}