Javascript模块模式 - 如何揭示所有方法?

时间:2013-03-18 15:31:23

标签: javascript unit-testing tdd module-pattern

我有这样的模块模式:

var A = (function(x) {
   var methodA = function() { ... }
   var methodB = function() { ... }
   var methodC = function() { ... }
   ...
   ...
   return {
      methA: methodA,
      methB: methodB
   }
})(window)

此代码让我只调用methB()上的methA和A,这就是我想要的和我喜欢的。现在我遇到了这个问题 - 我想对它进行单元测试 ,至少在最小的努力下没有任何痛苦。


首先 我虽然可以简单地返回this,但我错了。它返回window个对象。(有人可以解释原因吗?)。

第二次 - 我在网上找到了解决方案 - 在我的返回区块中包含此方法:

__exec: function() {
    var re = /(\(\))$/,
        args = [].slice.call(arguments),
        name = args.shift(),
        is_method = re.test(name),
        name = name.replace(re, ''),
        target = eval(name);
    return is_method ? target.apply(this, args) : target;
}

这个方法让我调用这样的方法:A.__exec('methA', arguments); 这几乎是我想要的,但非常难看。我希望A.test.methA() test永远不会在生产代码中使用 - 只是为了揭示隐私方法。


修改 我看到有人告诉我测试大件而不是小件。让我解释。在我看来,API应该只显示所需的方法而不是一堆内部函数。内部因为它们的小尺寸和有限的功能而更容易测试然后测试整个事情并猜测哪个部分出了问题。

虽然我可能错了,但我仍然希望看到如何从对象本身返回对所有方法的引用:)。

2 个答案:

答案 0 :(得分:2)

回答你的第一个问题(你返回这个,但它返回窗口,而不是你想要的对象):在函数内部的javascript this中返回全局对象,除非这个函数是对象的方法。

考虑下一个例子:

1)this指向全局对象():

function(){
   return this;
}

2)this指向对象:

var obj = {
    value: "foo",
    getThisObject: function(){
        return this;
    }
}

您的案例是示例#1,因为您有一个返回对象的函数。此函数不是任何对象的方法。

第二个问题的最佳答案是仅测试公共方法,但是如果 这对你来说非常重要,我可以提出下一步:

在服务器端动态创建模块。

工作原理:

  • 为您想要的功能创建单独的脚本;
  • 为这些单独的脚本创建测试;
  • 创建方法,将脚本组合成一个你想要的;
  • 加载脚本,引用组合脚本方法。

希望它可以解决您的问题。祝你好运!

答案 1 :(得分:0)

为什么不使用命名空间将模块和公共方法添加到js引擎。像这样:

window['MyApp']['MODULE1'] = { "METHOD1" : {}, "METHOD2" : {}}; 

我写这样的模块Sample module in JavaScript

并按照以下方式进行测试:Simple unit testing in JavaScript

使用eval()通常不是一个好主意。