【问题标题】:"before all" hook randomly showing up in my tests“首先”钩子随机出现在我的测试中
【发布时间】:2018-06-12 09:06:51
【问题描述】:

我目前正在运行一个堆栈,该堆栈由 Express 和 MongoClient 以及 Mocha 和 Chai 组成,用于测试。我正在为我的端点编写测试用例,并且不时出现随机错误。下面是我正在写的一套西装的 sn-p:

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() 方法只接受一个名称并返回一个被解析为true/false 值的承诺。我已经做了一些调试,它工作得很好。我遇到问题的地方是当我点击我调用createCollection 的代码部分时。我收到关于集合如何存在的错误,从而导致我的测试失败。这似乎在我每三次运行测试时都会发生。

所有这些的目的是确保我的名为 recipes 的数据库集合在我开始测试之前是完全空的,这样我就不会被旧数据卡住或处于不受控制的环境中。

【问题讨论】:

    标签: node.js automated-tests mocha.js chai


    【解决方案1】:

    .createCollection.insertOne 之间存在竞争条件。换句话说,它们同时开始并并行进行。没有办法知道哪个会先完成。

    .insert 在 MongoDB 中的工作方式是,如果集合丢失并且您尝试插入 - 它将创建一个集合。因此,如果首先执行 .insertOne - 将创建集合,这就是为什么您在尝试 createCollection 时收到 already exists 错误。

    由于 DB 调用的异步特性,您必须将后续调用放在 prev 的回调中。一。这样就不会有并行执行:

    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);
        });
    });

    【讨论】:

    • 我认为是这样的情况。但如果是这样的话,为什么我每三次都能重现错误?
    • @MichaelPlatt 它是随机发生的。不能保证您只会每 3 次获得它。如果 insertOne 先完成 - 你会得到错误。如果createCollection - 没有错误。
    • 嗯好的。我想我只是太不走运了,当我测试它时,它确实每三次发生一次。感谢您为我清理它先生!
    • @MichaelPlatt 我很高兴能帮上忙!祝你好运!
    猜你喜欢
    • 2018-06-13
    • 1970-01-01
    • 2015-02-17
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多