【问题标题】:Unit testing node.js model code accessing mongodb, without actually accessing the database单元测试node.js模型代码访问mongodb,没有实际访问数据库
【发布时间】:2026-02-14 04:25:02
【问题描述】:

例如,我有下面的代码:

var db = require('./_mongo.js');
module.exports = {
    check: function (cb) {
        var content = {};
        content.collection = 'counters';
        content.query = {_id: 'ping'};
        content.columns = {};
        db.read(content, function(err, result){
            if (err) {
                cb(-1);
            }
            else {
                cb(0);
            }
        });
    }
};

如何在不实际访问数据库的情况下为“检查”函数编写单元测试,同时检查是否能够编写正确的“内容”变量并传递给读取方法?

【问题讨论】:

    标签: node.js unit-testing mocking


    【解决方案1】:

    您可以使用模拟框架模拟整个模块,例如sinon.js

    var db = sinon.mock(require('_mongo.js'))
    

    我不建议模拟数据库访问,它可能需要您编写所有可能的响应...

    最好将数据库访问隐藏在抽象服务层后面并模拟该层。

    例如,可以这样创建数据库访问层:

    var db = require('./_mongo.js');
    module.exports = {
        //this is a mockable method
        getCounter: function (id, callback) {
            var content = {};
            content.collection = 'counters';
            content.query = {_id: id};
            content.columns = {};
            db.read(content, callback);
        }
    };
    
    //and then using it
    module.exports = {
        check: function (cb) {
            //access the actual method or the mock
            da.getCounter('ping', function(err, result){
                if (err) {
                    cb(-1);
                }
                else {
                    cb(0);
                }
            });
        }
    };
    

    【讨论】:

      【解决方案2】:

      test-studio 提供了排除模块依赖关系的机制。它还支持执行单个或一组测试以及将节点检查器单步执行到单个测试中。

      阅读更多信息here

      【讨论】: