【问题标题】:Testing JavaScript functions inside anonymous functions在匿名函数中测试 JavaScript 函数
【发布时间】:2009-12-10 13:46:02
【问题描述】:

下面可以测试myInnerFunction吗?

var val = function() {
    var myInnerfunction = function(input) {
        return input + ' I ADDED THIS';
    };
    return myInnerfunction('test value');
}();

因为myInnerFunction 本质上是匿名执行的外部函数的私有成员,所以它似乎无法从外部测试。

【问题讨论】:

  • 答案现在提出了一个更广泛的问题。这是一个微不足道的例子。我有 JS 函数,它们与预期的 DOM 结构紧密相关,它们与之耦合,并且不能被拉入通用公共实用程序 API。我需要测试这些功能;它们的逻辑很重要,但它们都在函数文字中声明为 on-DOM-ready,并作为事件处理程序附加到 DOM 元素。它们本质上是私有的,并且与 DOM 结构紧密耦合,但我仍然需要测试它们。为了让我能够从我的测试中访问它们,它们应该驻留在哪里?
  • 为了将我想测试的方法从库中执行的on-dom-ready的匿名函数中取出,我将它们命名在一个与正在进行的功能相对应的“包”中在我的页面中。虽然这段代码实际上只会在这个特定的页面上使用,并且只能通过我添加到这个特定 DOM 的事件处理程序,但至少我现在可以测试这个逻辑了。谢谢大家指导我。欢迎任何进一步的想法。

标签: javascript testing


【解决方案1】:

你可以故意向外界公开一个测试钩子,可能像这样:

var val = function() {
   var myInnerfunction = function(input) {
      return input + ' I ADDED THIS';
   };
   /* START test hook */
   arguments.callee.__test_inner = myInnerFunction;
   /* END test hook */
   return myInnerfunction('test value');
}();

现在,一旦 val 至少运行一次,您可以引用 val.__test_inner 并使用可测试的输入调用它。

这种方法的好处: 1.你选择什么是暴露的而不是暴露的(也是一个负面的,因为你必须记住这样做) 2.你得到的只是对私有方法的复制引用,所以你不能不小心改变它,只使用它,看看它产生了什么

缺点: 1. 如果私有成员更改(或依赖)其主机/父函数的状态,您就很难围绕它进行单元测试,因为您必须同时重新创建或人为控制主机/父状态 2. 如前所述,这些钩子必须手动添加

如果你真的很聪明,你可以让你的构建过程像上面那样查找 cmets 块,并在创建生产构建时删除测试钩子。

【讨论】:

  • 我喜欢你的方法,虽然我确实想尽量保持生产代码尽可能干净。我真正要做的是为库的 Dom-ready 事件处理程序提供一个函数,所以我不知道我是否可以这样做并且仍然可以从库中访问它。
  • 这正是我建议构建过程像上面那样删除格式化的 cmets 块的原因。
【解决方案2】:

afaik 单元测试不关心您测试的事物的内部运作。关键是您要测试功能,即:它做了什么 它应该做的,而不是它如何做。 因此,如果它使用内部私有成员,它应该不可测试...

【讨论】:

    【解决方案3】:

    您可以测试可观察到的外部行为。在这个简单的例子中,您只返回了内部函数的值,但在现实世界的示例中,您可能会将该内部函数的结果与其他内容结合起来。该组合是您要测试的,而不是私有方法的直接输出。

    尝试测试私有方法将使您的代码难以更改和重构,即使保留了外部行为也是如此。也就是说,我不喜欢将单元测试视为对代码的广泛测试,而只是提供 API 的示例以及它在不同条件下的行为方式。 ;)

    【讨论】:

      【解决方案4】:

      我认为我对此的回答是(就像很多事情一样)我做错了。我定义为“私有”功能的东西确实需要测试。它只是私有的,因为我不想在实用程序 api 或类似的东西中公开它。但它仍然可以通过我的应用程序命名空间公开。

      所以在on-dom-ready 执行的匿名函数中,我只是将我的预定义函数作为事件处理程序附加到适当的DOM 挂钩。这些函数本身虽然没有与我更开放的实用程序函数一起存储,但仍公开存储在我的命名空间中的一个包中,与它们正在处理的 DOM 结构相关联。这样我就可以找到它们并适当地测试它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        • 2010-11-06
        • 1970-01-01
        相关资源
        最近更新 更多