正在测试带有注入依赖的node js模块

Testing node js module with injected dependecy

本文关键字:node js 模块 依赖 注入 测试      更新时间:2023-09-26

我是java, c#程序员,有10多年的经验。现在我要用js写一些代码,感觉就像《爱丽丝梦游仙境》....

我有myModule.js:
module.exports = function (logger) {
return {
    read: function (param) {
        ......
        logger.eror(....)
    },
    write: function (param) {
        ......
        logger.info(....)
    }
};

}

logger.js,(遗留代码,我不能更改它)看起来类似:

module.exports = function(some_settings){
 return {
    info: function () {
        ......
    },
    error: function () {
        ......
    }
};
}
重要的是:logger没有被require("logger")包含到myModule中,而是被注入到一些"全局" index.js文件中,看起来像:
var settings = require("../someSettings.js")();
var logger = require("../logger.js")(settings);
var myModule = require("../myModule .js")(logger);

现在我想在mocha中为myModule编写UT。我想模拟logger。我面对着墙。我尝试了proxyquire,但这不是很好的解决方案,因为logger不包含在myModule中。我尝试了sinon stub和mock,例如:

var logger = require("logger.js");
var loggerMock = sinon.mock(logger);
var myModule= require("myModule.js")(loggerMock);

或:

var logger = require("logger.js");
var loggerStub = sinon.stub(logger, "info", function() {return ....});
var myModule= require("myModule.js")(loggerStub);

但我仍然有一些错误,如:"试图将未定义的属性错误包装为函数"…

当你在测试你的模块时,你可以使用一个伪对象作为你的记录器对象,即:

const logger = {info: noop, error: noop, debug:...};
function noop() {}

或者我们用sinonjs创建一个模拟对象,如果您喜欢以编程方式创建它并使用spy功能。

然后,你可以注入它,将你的模块定义包装在一个闭包中(正如你所发布的):

# myModule.js:
module.exports = (dep1, dep2, ...) => {
  // module definition
}

或者使用rewire包,"注入"模块范围的依赖(它只适用于本地变量,不需要在模块中创建闭包):

# myModuleTest    
myModule = rewire('./myModule');
myModule.__set__('logger', { /* fake logger */ });