我试图弄清楚如何测试nodejs中的内部(即未导出)函数(最好使用mocha或jasmine) . 我不知道!
假设我有一个这样的模块:
function exported(i) {
return notExported(i) + 1;
}
function notExported(i) {
return i*2;
}
exports.exported = exported;
以下测试(摩卡):
var assert = require('assert'),
test = require('../modules/core/test');
describe('test', function(){
describe('#exported(i)', function(){
it('should return (i*2)+1 for any given i', function(){
assert.equal(3, test.exported(1));
assert.equal(5, test.exported(2));
});
});
});
有没有办法单独测试 notExported
函数而不实际导出它,因为它不打算暴露?
7 回答
rewire模块绝对是答案 .
这是我访问未导出函数并使用Mocha测试它的代码 .
application.js中:
test.js:
诀窍是将
NODE_ENV
环境变量设置为test
,然后有条件地导出它 .假设您没有全局安装mocha,您可以在app目录的根目录中包含Makefile,其中包含以下内容:
此make文件在运行mocha之前设置NODE_ENV . 然后,您可以在命令行使用
make test
运行mocha测试 .现在,您可以有条件地导出通常只有在运行mocha测试时才导出的函数:
另一个答案建议使用vm模块来评估文件,但这不起作用并抛出错误,指出未定义导出 .
编辑:
使用
vm
加载模块可能会导致意外行为(例如,instanceof
运算符不再适用于在此类模块中创建的对象,因为全局原型与通常使用require
加载的模块中使用的原型不同) . 我不再使用以下技术而是使用rewire模块 . 它运作得很好 . 这是我原来的答案:阐述srosh的回答......
感觉有点hacky,但是我写了一个简单的“test_utils.js”模块,它可以让你在你的应用程序模块中没有条件导出的情况下做你想做的事情:
节点模块的gobal
module
对象中还包含更多可能需要进入上述context
对象的内容,但这是我需要它工作的最小集合 .以下是使用mocha BDD的示例:
我发现了一种非常简单的方法,允许您在测试中测试,监视和模拟这些内部函数:
假设我们有一个这样的节点模块:
如果我们现在要测试 and spy and mock
myInternalFn
while not exporting it in production ,我们必须像这样改进文件:现在你可以测试, Spy 和模拟
myInternalFn
你在哪里使用它作为testable.myInternalFn
并且在 生产环境 中它是 not exported .与Jasmine合作,我试图根据rewire深入了解solution proposed by Anthony Mayfield .
我实现了以下功能( Caution :尚未经过全面测试,只是作为一种可能的策略共享):
使用这样的函数,您可以监视非导出对象和非导出顶级函数的两种方法,如下所示:
然后你可以设置这样的期望:
你可以使用vm模块创建一个新的上下文并在其中评估js文件,有点像repl . 然后你可以访问它声明的所有内容 .
这不是推荐的做法,但是如果你不能按照@Antoine的建议使用
rewire
,你总是可以只读取文件并使用eval()
.我发现这对于遗留系统的单元测试客户端JS文件非常有用 .
JS文件将在
window
下设置许多全局变量,而没有任何require(...)
和module.exports
语句(没有像Webpack或Browserify这样的模块捆绑器可用于删除这些语句) .这不是重构整个代码库,而是允许我们在客户端JS中集成单元测试 .