使用 mocha 进行所有测试后在哪里删除数据库并关闭连接

Posted

技术标签:

【中文标题】使用 mocha 进行所有测试后在哪里删除数据库并关闭连接【英文标题】:where to delete database and close connection after all tests using mocha 【发布时间】:2012-12-03 15:23:21 【问题描述】:

我正试图找出在所有测试运行后将删除数据库和关闭连接的函数放在哪里。

这是我的嵌套测试:

//db.connection.db.dropDatabase();
//db.connection.close();

describe('User', function()
    beforeEach(function(done)
    );

    after(function(done)
    );

    describe('#save()', function()
        beforeEach(function(done)
        );

        it('should have username property', function(done)
            user.save(function(err, user)
                done();
            );
        );

        // now try a negative test
        it('should not save if username is not present', function(done)
            user.save(function(err, user)
                done();
            );
        );
    );

    describe('#find()', function()
        beforeEach(function(done)
            user.save(function(err, user)
                done();
            );
        );

        it('should find user by email', function(done)
            User.findOne(email: fakeUser.email, function(err, user)
                done();
            );
        );

        it('should find user by username', function(done)
            User.findOne(username: fakeUser.username, function(err, user)
                done();
            );
        );
    );
);

似乎没有任何效果。我得到错误:超过 2000 毫秒的超时

【问题讨论】:

【参考方案1】:

您可以在第一个 describe() 之前定义一个“根”after() 挂钩来处理清理:

after(function (done) 
    db.connection.db.dropDatabase(function () 
        db.connection.close(function () 
            done();
        );
    );
);

describe('User', ...);

不过,您遇到的错误可能来自 3 个异步钩子,它们没有通知 Mocha 继续。这些需要调用done() 或跳过参数,以便它们可以被视为同步:

describe('User', function()
    beforeEach(function(done) // arg = asynchronous
        done();
    );

    after(function(done)
        done()
    );

    describe('#save()', function()
        beforeEach(function() // no arg = synchronous
        );

        // ...
    );
);

From the docs:

通过向it() 添加回调(通常命名为done),Mocha 将知道它应该等待完成。

【讨论】:

实际上,我在第二次运行 make test 时收到此错误:` ✖ 5 个测试中有 1 个失败:1) 用户 #save() "before each" hook: Error: timeout of 2000ms exceeded` @chovy 它给了你方向——'"before each" hook"。所以,你有一个beforeEach 没有完成,可能是因为你'已将参数命名为接受回调,但随后没有调用它。使用 Mocha,您必须将其保留为未命名(0 个参数) -- function () ... -- 或命名并调用它 -- function (done) done(); 我现在得到一个不同的错误:gist.github.com/a8217751061ad6e738b9 1) “毕竟”钩子:错误:超过 2000 毫秒的超时 @chovy 错误的来源似乎不在该文件中。不过,我运行了一个稍微修改过的版本:gist.github.com/77caf41f4ee62a7fedc0 我不得不将我的 --timeout 设置为 4000,因为删除数据库显然会滞后一两秒。【参考方案2】:

我实现的有点不同。

    我删除了“before”挂钩中的所有文档 - 发现它比 dropDatabase() 快得多。

    我使用 Promise.all() 确保在退出钩子之前删除了所有文档。

    beforeEach(function (done) 
    
        function clearDB() 
            var promises = [
                Model1.remove().exec(),
                Model2.remove().exec(),
                Model3.remove().exec()
            ];
    
            Promise.all(promises)
                .then(function () 
                    done();
                )
        
    
        if (mongoose.connection.readyState === 0) 
            mongoose.connect(config.dbUrl, function (err) 
                if (err) 
                    throw err;
                
                return clearDB();
            );
         else 
            return clearDB();
        
    );
    

【讨论】:

以上是关于使用 mocha 进行所有测试后在哪里删除数据库并关闭连接的主要内容,如果未能解决你的问题,请参考以下文章

Meteor 中的单元测试应该放在哪里?

将变量传递给 Mocha 测试套件

使用 mocha 测试 express 服务器并使用异步初始化程序进行 supertest 调用请求两次

Mocha 单元测试框架简介

使用 typescript/mocha 进行单元测试时找不到模块

使用 Mocha 进行 JavaScript 代码自动化测试