"before all" 挂钩随机出现在我的测试中
"before all" hook randomly showing up in my tests
我目前 运行 一个由 Express 和 MongoClient 以及 Mocha 和 Chai 组成的堆栈用于测试。我正在为我的端点编写测试用例,但我收到了一个不时弹出的随机错误。下面是我正在写的一套西装的片段:
describe('Recipes with populated database', () => {
before((done) => {
var recipe1 = {"search_name": "mikes_mac_and_cheese", "text_friendly_name": "Mikes Mac and Cheese","ingredients": [{"name": "elbow_noodles","text_friendly_name": "elbow noodles","quantity": 12,"measurement": "oz"},{"name": "cheddar_cheese","text_friendly_name": "cheddar cheese","quantity": 6,"measurement": "oz"},{"name": "gouda_cheese","text_friendly_name": "gouda cheese","quantity": 6,"measurement": "oz"},{"name": "milk","text_friendly_name": "milk","quantity": 2,"measurement": "oz"}],"steps": ["Bring water to a boil","Cook noodels until al dente.","Add the milk and cheeses and melt down.","Stir constantly to ensure even coating and serve."],"course": ["dinner","lunch","side"],"prep_time": {"minutes": 15,"hours": 0},"cook_time":{"minutes": 25,"hours": 1},"cuisine": "italian","submitted_by": "User1","searchable": true};
db.collectionExists('recipes').then((exists) => {
if (exists) {
db.getDb().dropCollection('recipes', (err, results) => {
if (err)
{
throw err;
}
});
}
db.getDb().createCollection('recipes', (err, results) => {
if (err)
{
throw err;
}
});
db.getDb().collection('recipes').insertOne(recipe1, (err, result) => {
done();
});
});
});
collectionExists()
方法只接受一个名称和 returns 一个解析为 true/false
值的承诺。我已经完成了一些调试并且工作正常。我遇到问题的地方是当我点击调用 createCollection
的代码部分时。我收到有关集合如何存在的错误,从而导致我的测试失败。这似乎每三次发生一次,我也是 运行 我的测试。
所有这一切的目的是确保我的名为 recipes
的数据库集合在我开始测试之前是完全空的,这样我就不会被旧数据困住或处于不受控制的环境中。
您在 .createCollection
和 .insertOne
之间存在竞争条件。换句话说,它们同时开始并并行进行。无法判断哪个先完成。
.insert
在 MongoDB 中的工作方式是,如果集合丢失并且您尝试插入 - 它会创建一个集合。因此,如果首先执行 .insertOne
- 将创建集合,这就是为什么您在尝试 createCollection
.
时收到 already exists
错误的原因
由于数据库调用的异步性质,您必须将后续调用放在上一个回调中。一。这样就不会有并行执行了:
before((done) => {
var recipe1 = {/**/};
db.collectionExists('recipes')
.then((exists) => {
if (exists) {
// Drop the collection if it exists.
db.getDb().dropCollection('recipes', (err) => {
if (err) {
// If there's an error we want to pass it up to before.
done(err);
return;
}
// Just insert a first document into a non-existent collection.
// It's going to be created.
// Notice the done callback.
db.getDb().collection('recipes').insertOne(recipe1, done);
});
}
// If there were no such collection - simply insert the first doc to create it.
// Note that I'm passing before's done callback inside.
db.getDb().collection('recipes').insertOne(recipe1, done);
})
// We don't want to lose the error from this promise always.
.catch(err => done(err));
});
但是。实际上,每次 运行 测试时都不需要删除并重新创建一个集合。您可以简单地 .remove
before
块中的所有对象。所以可能正确的解决方案是:
before((done) => {
var recipe1 = {/**/};
const recipes = db.getDb().collection('recipes');
// Simply wipe out the data
recipes.remove({}, err => {
if (err) {
done(err);
return;
}
recipes.insertOne(recipe1, done);
});
});
我目前 运行 一个由 Express 和 MongoClient 以及 Mocha 和 Chai 组成的堆栈用于测试。我正在为我的端点编写测试用例,但我收到了一个不时弹出的随机错误。下面是我正在写的一套西装的片段:
describe('Recipes with populated database', () => {
before((done) => {
var recipe1 = {"search_name": "mikes_mac_and_cheese", "text_friendly_name": "Mikes Mac and Cheese","ingredients": [{"name": "elbow_noodles","text_friendly_name": "elbow noodles","quantity": 12,"measurement": "oz"},{"name": "cheddar_cheese","text_friendly_name": "cheddar cheese","quantity": 6,"measurement": "oz"},{"name": "gouda_cheese","text_friendly_name": "gouda cheese","quantity": 6,"measurement": "oz"},{"name": "milk","text_friendly_name": "milk","quantity": 2,"measurement": "oz"}],"steps": ["Bring water to a boil","Cook noodels until al dente.","Add the milk and cheeses and melt down.","Stir constantly to ensure even coating and serve."],"course": ["dinner","lunch","side"],"prep_time": {"minutes": 15,"hours": 0},"cook_time":{"minutes": 25,"hours": 1},"cuisine": "italian","submitted_by": "User1","searchable": true};
db.collectionExists('recipes').then((exists) => {
if (exists) {
db.getDb().dropCollection('recipes', (err, results) => {
if (err)
{
throw err;
}
});
}
db.getDb().createCollection('recipes', (err, results) => {
if (err)
{
throw err;
}
});
db.getDb().collection('recipes').insertOne(recipe1, (err, result) => {
done();
});
});
});
collectionExists()
方法只接受一个名称和 returns 一个解析为 true/false
值的承诺。我已经完成了一些调试并且工作正常。我遇到问题的地方是当我点击调用 createCollection
的代码部分时。我收到有关集合如何存在的错误,从而导致我的测试失败。这似乎每三次发生一次,我也是 运行 我的测试。
所有这一切的目的是确保我的名为 recipes
的数据库集合在我开始测试之前是完全空的,这样我就不会被旧数据困住或处于不受控制的环境中。
您在 .createCollection
和 .insertOne
之间存在竞争条件。换句话说,它们同时开始并并行进行。无法判断哪个先完成。
.insert
在 MongoDB 中的工作方式是,如果集合丢失并且您尝试插入 - 它会创建一个集合。因此,如果首先执行 .insertOne
- 将创建集合,这就是为什么您在尝试 createCollection
.
already exists
错误的原因
由于数据库调用的异步性质,您必须将后续调用放在上一个回调中。一。这样就不会有并行执行了:
before((done) => {
var recipe1 = {/**/};
db.collectionExists('recipes')
.then((exists) => {
if (exists) {
// Drop the collection if it exists.
db.getDb().dropCollection('recipes', (err) => {
if (err) {
// If there's an error we want to pass it up to before.
done(err);
return;
}
// Just insert a first document into a non-existent collection.
// It's going to be created.
// Notice the done callback.
db.getDb().collection('recipes').insertOne(recipe1, done);
});
}
// If there were no such collection - simply insert the first doc to create it.
// Note that I'm passing before's done callback inside.
db.getDb().collection('recipes').insertOne(recipe1, done);
})
// We don't want to lose the error from this promise always.
.catch(err => done(err));
});
但是。实际上,每次 运行 测试时都不需要删除并重新创建一个集合。您可以简单地 .remove
before
块中的所有对象。所以可能正确的解决方案是:
before((done) => {
var recipe1 = {/**/};
const recipes = db.getDb().collection('recipes');
// Simply wipe out the data
recipes.remove({}, err => {
if (err) {
done(err);
return;
}
recipes.insertOne(recipe1, done);
});
});