QUnit + coffeescript范围

时间:2011-06-24 23:23:16

标签: coffeescript qunit

在Javascript中污染全局命名空间通常被认为是一件坏事。这就是为什么Coffeescript将所有Javascript包装在(function() {}).call(this);包装器中。

然而,我已经开始为我的Coffeescript代码编写QUnit测试,并且QUnit抱怨它无法找到我的函数。

1. Died on test #1: getGoodNamePart is not defined
getGoodNamePart is not defined at Object.<anonymous> (file:///Users/kevin/Documents/docs/code/chrome/tests.js:2:10) at Object.run 

我想在不污染全局命名空间的情况下测试变量。有什么好办法呢?

这是我要测试的生成的Javascript:

(function() {
getGoodNamePart = function(str) {
    if (str.charAt(0) === '"') {
      str.replace(/" <[^>]+>$"/g, "");
      str.replace(/"/g, "");
      return str;
    } else if (str.charAt(0) === '<') {
      str.replace(/<|>/g, "");
      return str;
    } else {
      return str;
    }
  };
}).call(this);

我的test.js文件是:

test('getGoodNamePart()', function() {
  equals(getGoodNamePart("\"Kev Burke\" <kev@inburke.com>"), "Kev Burke", "\"name\" <email> works");
  equals(getGoodNamePart("", "", "empty string works"));
  equals(getGoodNamePart("kev@inburke.com", "kev@inburke.com", "raw email works"));
  return equals(getGoodNamePart("<kev@inburke.com>", "kev@inburke.com", "email inside carets -> carets get stripped"));
});

谢谢, 凯文

2 个答案:

答案 0 :(得分:6)

因此,您说要在不污染全局命名空间的情况下测试getGoodNamePart。但是,CoffeeScript会自动模块化每个文件(有充分的理由 - 请参阅my answer here),这意味着跨文件访问函数的唯一方法是将它们附加到某个全局对象。 (我假设我们在这里讨论的是浏览器,而不是CommonJS环境,例如Node.js,你使用exports。)

这给你三个选择:

  1. getGoodNamePart附加到window。这是最简单的,因为唯一需要做的更改是在getGoodNamePart前加上window.(或只是@),但这当然会最大化名称空间污染。
  2. getGoodNamePart附加到已附加到windowglobal的其他内容。
  3. 将您的测试移动到与getGoodNamePart相同的文件中(这是JS世界中一种不同寻常的做法,但值得考虑,因为它保持全局命名空间不变,让您轻松地在代码和测试之间切换)
  4. 假设您想要使用#2,仅将getGoodNamePart等函数导出为测试。称他们为“测试目标”。在包含测试目标的每个文件的顶部,添加

    window.testTargets ?= {}
    

    当您定义getGoodNamePart时,请写

    testTargets.getGoodNamePart = getGoodNamePart = (str) ->
      ...
    

    然后在QUnit测试套件的顶部,写下

    {getGoodNamePart} = testTargets
    

    获得该功能。

答案 1 :(得分:2)