我试图在mongo数据库包装器上编写测试(规范)并偶然发现这个奇怪的问题。
我的代码构建在mongodb的瘦包装之上,将_id
作为字符串暴露给世界,但在与mongo交谈时使用(转换)它们到ObjectId。
我是帮手创建灯具:
var _ = require('lodash'),
Promise = require('bluebird'),
MongoDb = require('mongodb');
var fixtureData = [
{
'uuid': '1',
'owner': 'A',
'data': 'someData1'
},
{
'uuid': '2',
'owner': 'A',
'data': 'someData2'
},
{
'uuid': '3',
'owner': 'B',
'data': 'someData3'
},
{
'uuid': '4',
'owner': 'A',
'data': 'someData4'
},
{
'uuid': '5',
'owner': 'A',
'data': 'someData5'
},
{
'uuid': '6',
'owner': 'B',
'data': 'someData6'
}
]
module.exports.loadFixtures = function (url, collectionName) {
var MongoClient = MongoDb.MongoClient;
return MongoClient.connect(url, {
promiseLibrary: Promise
}).then(function (db) {
return db.dropCollection(collectionName)
.catch(function (err) {
if (err.message === 'ns not found') {
return 'does not exist';
}
throw err;
})
.then(function () {
return db.collection(collectionName).insertMany(fixtureData);
}).then(function (result) {
_.forEach(result.insertedIds, function (value, idx) {
fixtureData[idx]._id = value;
});
return db;
});
}).then(function (db) {
db.close();
return fixtureData;
});
};
我使用jasmine进行测试,我在每个beforeEach调用它,以便始终以相同的情况开始每个测试。
然后我有一个测试删除的功能(简单地说):
var dataToDelete = fixtureData[0];
sut.deleteDocument(dataToDelete_.id)
.then(function(result) {
expect(....);
});
在我的deleteDocument中,我没有做任何特别的事情:
db.collection('myCollection').deleteOne({ _id: theId })
then(function(result)) {
if (result.deletedCount === 0) {
throw new Error('No document to delete with ID: ' + _id);
}
return null;
});
这里的theId
变量是通过一个非常简单的函数在mongo ObjectId
转换为参数传递的参数获得的:
function (id) {
if (_.isString(id)) {
return MongoDb.ObjectId(id);
}
if (MongoDb.ObjectId.isValid(id) === true) {
return id;
}
throw new Error('Invalid ObjectId');
};
我正在使用mongodb Node.js驱动程序版本2.2.16
。
这里的问题是,如果我使用deletedCount = 0
作为ObjectId
,我总是会收到_id
,但如果我将其转换为字符串,则可以使用并删除该函数。
这完全困扰我,因为我发现的每个文档和每个示例总是说_id
是ObjectId
。
有人能解释一下发生了什么吗?
编辑:(答案让我朝着正确的方向前进,但如果你最终遇到这种情况,这就是你正在寻找的真正的答案)如果你在这种情况下结束了你在_id
传递字符串创建文档时的字段。如果不是这样的话,请找出你为什么这样做并且你要解决它
答案 0 :(得分:1)
你确定你的灯具在不同的测试之间没有受损吗?
顺便说一句不应该
return MongoDb.ObjectId(id);
是
return new MongoDb.ObjectId(id);