1

我为 Node.js 编写了自己的瘦 mongodb 包装器,以消除代码重复。

但是,我在使用 Mocha 和 Should 运行异步单元测试时遇到问题。

发生的情况是,应该库抛出的任何异常都被 MongoDB 驱动程序而不是 Mocha 捕获。也就是说,Mocha 都没有捕捉到错误,也没有调用 done() 函数。结果,Mocha 打印出一个错误Error: timeout of 2000ms exceeded

包装模块的片段db.js

var mongodb = require('mongodb').MongoClient;

exports.getCollection = function(name, callback) {
    mongodb.connect(dbConfig.dbURI, {auto_reconnect: true}, function(err, db) {
        if (err)
            return callback(err, null);

        db.collection(name, {strict: true}, callback);
    });
};

摩卡test.js

var should = require('should');
var db     = require('./db.js');

describe('Collections', function() {
    it.only('should retrieve user collection', function(done) {
        db.getCollection('user', function(err, coll) {
            should.not.exist(err);
            coll.should.be.a('object');
            // HERE goes an assertion ERROR
            coll.collectionName.should.equal('user123');

            done();
        });
    });
});

同样的行为可以通过这个简单的来模拟test.js

var should = require('should');

var obj = {
    call: function(callback) {
        try {
            console.log('Running callback(null);');
            return callback(null);
        }
        catch(e) {
            console.log('Catched an error:', e);
        }
    }
};

describe('Test', function() {
    it('should catch an error', function(done) {
        obj.call(function(err) {
            should.exist(err);
            done();
        });
    });
});

有没有办法解决这个问题?必须有一种方法来测试这样的代码。

4

1 回答 1

1

偶然的运气,我发现了一个处理不同问题的 GitHub 分支,但代码让我意识到我可以使用一个简单的技巧让 Mocha 捕获断言异常:

describe('Test', function() {
    it('should catch an error', function(done) {
        obj.call(function(err) {
            try {
                should.exist(err);
                done();
            } catch (err) {
                done(err);
            }
        });
    });
});

即将调用包装shouldtry/catch块并done(err)在 catch 部分调用完全符合预期:

  1. 如果没有发生断言错误,则测试成功
  2. 由于done()函数接受错误参数,在断言错误的情况下测试失败
于 2013-09-10T15:49:07.143 回答