我正在学习Node.js,并且想知道人们在单元测试时如何在模块中模拟依赖关系。
例如: 我有一个抽象我的MongoDB调用的模块。使用此模块的模块可能会开始这样的事情。
var myMongo = require("MyMongoModule");
// insert rest of the module here.
我想确保我单独测试这样一个模块,同时确保我的测试不会将记录/文档插入Mongo。
是否有我可以使用代理require()
的模块/包,所以我可以注入我自己的模拟?其他人通常如何解决这个问题?
答案 0 :(得分:1)
您可以使用依赖注入库,例如nCore
说实话,这很难实现嘲弄mongoDB API,这很复杂且非常重要。我估计大概需要一周的时间来模拟我使用的大多数mongo API,所以我只是在我的机器上测试一个本地的mongodb数据库(总是处于一个奇怪的状态)
然后使用nCore特定语法
// myModule.js
module.exports = {
myMethod: function () {
this.mongo.doStuff(...)
},
expose: ["myMethod"]
};
// test-myModule.js
var module = require("myModule")
module.mongo = mongoMock
assert(module.myMethod() === ...)
答案 1 :(得分:0)
在审核了Ryanos的建议以及npm上的Horaa包之后,我发现Google Group上的这个帖子指向了我Sandboxed-Module.
Sandboxed-Module允许我注入/覆盖require(),而不必为我的单元测试公开这样的依赖项。
我还在寻求其他建议;但是,Sandboxed-Module目前似乎符合我的需求。
答案 2 :(得分:0)
您可以使用“a”轻松模拟要求:https://npmjs.org/package/a
e.g。需要在单元测试中模拟require('./ foo'):
var fakeFoo = {};
var expectRequire = require('a')。expectRequire;
expectRequire(” ./富).return(fakeFoo);
//在sut中:
var foo = require('./ foo); //返回fakeFoo
答案 3 :(得分:0)
覆盖require
以注入你的模拟是一种可能的解决方案。但是,我同意雷诺斯的观点:
我个人觉得覆盖的方法需要逐个文件地“丑陋的黑客”,并且更愿意选择正确的DI。然而,它是在现有代码库上模拟一个或两个模块而不重写DI支持代码的最佳选择。
使用正确的依赖注入不仅可以为您节省“丑陋的黑客”,而且还允许您在注入模拟时应用其他用例。在生产中你可以例如通常通过http实例化连接,并在某些情况下注入不同的实现以通过VPN建立连接。
如果您想查找依赖注入容器,请阅读此excellent article并查看我实施的Fire Up!。