【发布时间】:2015-05-01 18:15:23
【问题描述】:
我正在用 nodejs 构建一个 REST api,使用 mongoose 和 mochajs 来运行一些测试。我有以下方案:
var subscriptionTypeSchema = new mongoose.Schema({
typeId : { type: Number, required: true, unique: true },
name : { type: String, required: true},
active : { type: Boolean, required: true }
});
快车路线:
app.post('/1.0/subscriptiontype', subscriptiontype.create);
控制器:
exports.create = function(req, res) {
validation.subscriptionTypeValidator(req);
var errors = req.validationErrors();
if (errors) {
res.status(400).json({
errors: errors
});
} else {
var subscriptionType = new SubscriptionType();
subscriptionType.typeId = parseInt(req.body.typeId);
subscriptionType.name = req.body.name;
subscriptionType.active = req.body.active;
subscriptionType.save(function(err) {
if (err) {
var parsedError = mongooseutility.parseMongooseError(err);
res.status(400).json({
errors: [parsedError]
});
} else {
res.json({identifier: subscriptionType._id});
}
});
}
};
mongoose 实用程序将错误代码映射到对 API 更友好的输出(错误代码 11001 和 11000 映射到“重复”错误,如测试中所示)。
Mocha 之前的方法:
before(function(done) {
db.connection.on('open', function() {
db.connection.db.dropDatabase(function(err) {
done();
});
});
});
我已验证成功删除数据库。
测试本身使用 supertest 发出请求。在这个测试之前,我有一个测试成功创建了 typeId 为 4 的订阅类型,所以这个应该失败:
it('Should not create subscription with taken type id', function (done) {
request(app.privateapi)
.post('/1.0/subscriptiontype')
.set('Authorization', authorizationHeader)
.send({
typeId: 4,
name: 'New package',
active: 1
})
.expect(function (res) {
if (res.status !== 400) {
throw new Error('Status code was not 400');
}
var expectedResponse = { errors: [ { param: 'typeId', msg: 'duplicate' } ] };
if (JSON.stringify(res.body) !== JSON.stringify(expectedResponse)) {
throw new Error('Output was not was as expected');
}
})
.end(done);
});
使用 grunt-simple-mocha 调用测试。
这个测试第一次运行,但是当我第二次运行它时,它在唯一验证上失败了。第三次它再次工作。我做了一些搜索,发现它可能与重新创建索引时的竞争条件有关,所以我尝试在再次运行测试之前重新启动 mongodb,但这不起作用。我在这里找到了解决方案:http://grokbase.com/t/gg/mongoose-orm/138qe75dvr/mongoose-unique-index-test-fail 但我不确定如何实现。有什么想法吗?
编辑:现在我通过在“之后”方法(而不是“之前”)中删除数据库来修复它。所有测试都运行良好,但最好在测试完成后保留测试数据,以供检查等...
【问题讨论】:
-
您愿意分享执行更新的实际代码和实际提交方法吗?也许考虑到已经存在了一段时间的软件比没有共享相同时间测试的全新代码出错的可能性更小。你分享得越多,其他人的眼睛就越能清楚地观察到实际问题。
-
感谢您的回复,我已经添加了更多信息。
-
我可以在这里指出您问题的症结所在吗?所以你说 1. 插入:好的,2. 插入:失败,3. 插入:好的。并且同时将相同的值提交到唯一的字段约束(AKA 索引)。因此,以一种理智的方式,这完全是关于调用以及实际收集工件在何时何地被“丢弃”。因此,虽然附加信息很有用,但实际情况是“您如何调用它”以及我们如何确保索引创建到位。参考帖子中暗示的内容。这是关于时间和继承的。如果您仍然需要帮助,那么这就是您的要求。
-
对,我不完全确定您的意思,但测试是通过 grunt-simple-mocha 任务调用的。 before() 方法是测试套件中第一个被调用的方法。