是否可以对闭包中存在的javascript函数进行单元测试,例如,给定以下内容:
(function() {
var a = function() {
//do something
}
window.b = function() {
// do something else
}
})();
是否可以在不暴露的情况下对单元测试功能进行单元测试?如果没有,是否有一种很好的方式来公开,但只能在测试模式下?
答案 0 :(得分:8)
您的匿名函数可以采用一个参数,该参数在未处于测试模式时是未定义的,并且说该参数将是一个对象,您可以使用a
填充对象而不直接暴露a
只是我的.02 $
答案 1 :(得分:3)
这里最大的问题是你为什么要隐藏它?您具有要测试的此功能的事实表明,a有自己的责任应该进行测试。将其拉出并使其受到测试可以获得更多的价值,同时权衡暴露它的最小风险。如果你真的想把它隐藏起来,那么我会建议类似于Manux的响应,你创建一个可以做但不直接暴露的对象。然后,您可以通过测试该对象来测试a的行为。
答案 2 :(得分:1)
重新审视这个问题4年后,我现在有了更好的解决方案。
说我正在使用Gulp来缩小我的JavaScript,我的代码看起来像这样:
var a = function() {}
window.b = function() {}
不是没有关闭。现在我设置了一个gulp任务,并让它看到我的代码,如下:
gulp.task('js', function () {
return gulp.src([dirs.js.src, '*.js'].join('/'))
.pipe(wrap('(function() {\n<%= contents %>\n})();'))
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(gulp.dest(dirs.js.dest));
});
这将把我的代码包装在IIFE中,产生以下输出:
(function() {
var a = function() {}
window.b = function() {}
)();
现在我添加另一个Gulp任务,就像这个
gulp.task('testJs', function () {
return gulp.src([dirs.test.src, '*.js'].join('/'))
.pipe(wrap(
[
'(function() {',
'<%= contents %>',
'// Smuggle locals out of closure for testing',
'window.a = a;',
'})();'
].join('\n')
))
.pipe(concat(package.name + '.testable.js'))
.pipe(gulp.dest(dirs.test.dest));
});
这将在我的测试目录中生成以下不安全但可测试的代码:
(function() {
var a = function() {}
window.b = function() {}
// Smuggle locals out of closure for testing
window.a = a;
)();
gulp.task('watch', function() {
gulp.watch([dirs.js.src, '**', '*.js'].join('/'), ['js', 'testJs']);
});
......你已经完成了。
见这里的例子: