模拟Node中的依赖项

时间:2012-03-01 15:50:35

标签: unit-testing node.js mocking

我正在学习Node.js,并且想知道人们在单元测试时如何在模块中模拟依赖关系。

例如: 我有一个抽象我的MongoDB调用的模块。使用此模块的模块可能会开始这样的事情。

var myMongo = require("MyMongoModule");
// insert rest of the module here.

我想确保我单独测试这样一个模块,同时确保我的测试不会将记录/文档插入Mongo。

是否有我可以使用代理require()的模块/包,所以我可以注入我自己的模拟?其他人通常如何解决这个问题?

4 个答案:

答案 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!