3

我有这样的模块模式:

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

这段代码让我只调用 methA ,methB()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()wheretest永远不会在生产代码中使用 - 只是为了揭示私有方法。


编辑 我看到人们告诉我要测试大的东西而不是小部分。让我解释。在我看来,API 应该只显示所需的方法,而不是一堆内部函数。由于它们的小尺寸和有限的功能,内部结构更容易测试,然后测试整个事物并猜测哪个部分出了问题。

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

4

2 回答 2

2

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

考虑下一个例子:

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

function(){
   return this;
}

2)this指向对象:

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

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

您的第二个问题的最佳答案是仅测试公共方法,但如果这对您来说如此重要,我可以提出以下建议:

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

这个怎么运作:

  • 为您想要的功能创建单独的脚本;
  • 为这些单独的脚本创建测试;
  • 创建可以将脚本组合成一个的方法;
  • 要加载脚本,请参考组合脚本方法。

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

于 2013-06-07T06:59:52.623 回答
0

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

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

在 JavaScript 中编写了像这个示例模块这样的模块。

并像这样测试它:JavaScript 中的简单单元测试

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

于 2013-03-18T16:39:23.740 回答