testingNode.js,模拟并testing一个需要的模块?

我正在努力围绕我的节点模块编写高质量的testing。 问题是需求模块系统。 我希望能够检查某个需要的模块是否有方法或其状态已经改变。 似乎有两个相对较小的库可以在这里使用: 节点轻轻地和嘲弄 。 然而,由于他们的“低调”,这使得我认为,任何人都不会对此进行testing,或者还有另外一种我不知道的方式。

嘲笑和testing需要的模块的最好方法是什么?


———– 更新 —————

节点 – 沙箱的工作原理与下面所述的相同,但包装在一个很好的模块中。 我发现这是非常好的工作。


————— 详细的awnser —————

经过大量的试验,我发现最好的方法来独立地testing节点模块,而嘲笑事情的方法是使用Vojta Jina的方法在这里解释一个新的上下文运行一个虚拟机的每个模块。

用这个testingvm模块:

var vm = require('vm'); var fs = require('fs'); var path = require('path'); /** * Helper for unit testing: * - load module with mocked dependencies * - allow accessing private state of the module * * @param {string} filePath Absolute path to module (file to load) * @param {Object=} mocks Hash of mocked dependencies */ exports.loadModule = function(filePath, mocks) { mocks = mocks || {}; // this is necessary to allow relative path modules within loaded file // ie requiring ./some inside file /a/b.js needs to be resolved to /a/some var resolveModule = function(module) { if (module.charAt(0) !== '.') return module; return path.resolve(path.dirname(filePath), module); }; var exports = {}; var context = { require: function(name) { return mocks[name] || require(resolveModule(name)); }, console: console, exports: exports, module: { exports: exports } }; vm.runInNewContext(fs.readFileSync(filePath), context); return context; }; 

可以使用自己的上下文testing每个模块,并轻松地将所有外部依赖关系排除在外。

 fsMock = mocks.createFs(); mockRequest = mocks.createRequest(); mockResponse = mocks.createResponse(); // load the module with mock fs instead of real fs // publish all the private state as an object module = loadModule('./web-server.js', {fs: fsMock}); 

我高度推荐这种方法来隔离编写有效的testing。 只有验收testing应该击中整个堆栈。 单元和集成testing应testing系统的隔离部分。

我认为嘲弄模式是一个很好的模式。 也就是说,我通常select将依赖关系作为参数发送给函数(类似于在构造函数中传递依赖关系)。

 // foo.js module.exports = function(dep1, dep2) { return { bar: function() { // A function doing stuff with dep1 and dep2 } } } 

当testing时,我可以发送模拟,空的对象,而不pipe似乎是合适的。 请注意,我不这样做的所有依赖关系,基本上只有IO – 我不觉得需要testing我的代码调用path.join或其他。

我认为让你紧张的“低调”是由于几件事情:

  • 有些人构build他们的代码类似于我的
  • 有些人有自己的帮手,实现了和嘲笑等人一样的目标(这是一个非常简单的模块)
  • 有些人不会单位testing这样的事情,而是旋转他们的应用程序(和数据库等)的实例,并进行testing。 更清洁的testing,而且服务器如此之快,不会影响testing性能。

总之,如果你认为嘲笑适合你,那就去做吧!

您可以通过使用“a”轻松模拟需求: https : //npmjs.org/package/a

 //Example faking require('./foo') in unit test: var fakeFoo = {}; var expectRequire = require('a').expectRequire; expectRequire('./foo).return(fakeFoo); //in sut: var foo = require('./foo); //returns fakeFoo