QUnit + coffeescript范围

Kev*_*rke 6 qunit coffeescript

在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 
Run Code Online (Sandbox Code Playgroud)

我想在不污染全局命名空间的情况下测试变量.这样做的好方法是什么?

这是我要测试的生成的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);
Run Code Online (Sandbox Code Playgroud)

我的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"));
});
Run Code Online (Sandbox Code Playgroud)

谢谢,凯文

Tre*_*ham 6

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

这给你三个选择:

  1. 连接getGoodNamePartwindow.这是最简单的,因为所需要的唯一的变化是前缀getGoodNamePartwindow.(或只@),但当然这最大化命名空间的污染.
  2. 附加getGoodNamePart到已经附加到的其他内容windowglobal.
  3. 将测试移到同一个文件中getGoodNamePart(在JS世界中是一种不同寻常的做法,但值得考虑的是,因为它保持全局命名空间不变,让您可以轻松地在代码和测试之间进行).

假设您想要使用#2,导出getGoodNamePart纯粹用于测试的功能.称他们为"测试目标".在每个带有测试目标的文件的顶部,添加

window.testTargets ?= {}
Run Code Online (Sandbox Code Playgroud)

当你定义getGoodNamePart,写

testTargets.getGoodNamePart = getGoodNamePart = (str) ->
  ...
Run Code Online (Sandbox Code Playgroud)

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

{getGoodNamePart} = testTargets
Run Code Online (Sandbox Code Playgroud)

获得这个功能.