【问题标题】:Javascript Module pattern - how to reveal all methods?Javascript 模块模式 - 如何显示所有方法?
【发布时间】:2013-03-07 00:19:30
【问题描述】:

我有这样的模块模式:

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

这段代码让我在A 上只调用methA 和methB(),这是我想要的和我喜欢的。现在我遇到的问题 - 我想对它进行单元测试,至少不费吹灰之力。


首先虽然我可以简单地返回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 应该只显示所需的方法,而不是一堆内部函数。内部结构由于体积小且功能有限,因此更容易测试,然后测试整个事物并猜测哪个部分出了问题。

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

【问题讨论】:

  • 你没有对私有方法进行单元测试,或者你没有将它们设为私有。这很简单。
  • @mpm 私有方法也是代码,因此也需要对其进行测试。
  • 这不是个好主意。私有方法是私有的,你不必将它们公开。测试您的公共方法,它们依赖于私有,因此测试公共也应该涵盖这一点。
  • @lukas.pukenis 然后公开,有什么复杂的?你想访问一些东西,把它公开。你不想然后将其设为私有。您可以使用组合在另一个对象中将某些内容设为公开私有。我不明白这里有什么问题。你不能两全其美,仅此而已。正如另一个问题(上)所述,TDD 是关于测试合同的。 TDD 不关心私有的。

标签: javascript unit-testing tdd module-pattern


【解决方案1】:

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

考虑下一个例子:

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

function(){
   return this;
}

2) this 指向对象:

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

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

第二个问题的最佳答案是仅测试公共方法,但如果 这对你很重要,我可以建议下一个:

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

它是如何工作的:

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

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

【讨论】:

    【解决方案2】:

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

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

    我写这样的模块Sample module in JavaScript

    并像这样测试它:Simple unit testing in JavaScript

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

    【讨论】:

    • 你可能是对的 eval() 但我认为它没有问题。它是一种语言结构,在某些情况下会有所帮助。
    猜你喜欢
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多