1

コードの繰り返しをなくすために、Node.js 用の独自の薄い mongodb ラッパーを作成しました。

ただし、Mocha と Should で実行される非同期単体テストに問題があります。

何が起こるかというと、Should ライブラリによってスローされた例外は、Mocha ではなく MongoDB ドライバーによってキャッチされます。つまり、Mocha がエラーをキャッチすることも、done() 関数が呼び出されることもありません。その結果、Mocha は error を出力します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);
            }
        });
    });
});

shouldつまり、呼び出しをtry/catchブロックにラップdone(err)し、catch セクションで呼び出すと、期待どおりのことが行われます。

  1. アサーション エラーが発生しなければ、テストは成功です
  2. done()関数がエラー引数を受け入れるため、アサーション エラーの場合にテストが失敗する
于 2013-09-10T15:49:07.143 に答える