尽管 StackOverflow 上有这两个相关的问题,但我还没有找到令人满意的答案,所以我发帖是为了了解 Jasmine-jQuery 用户中是否存在公认的最佳实践。
基本问题很简单,两个相关问题中涵盖了两个示例:
在我的 Javascript 中,有一个
setup()
函数可以将事件处理程序绑定到页面上的各种选择器,如$('#someDiv').click(someHandler)
; 这个函数被传递给$(document).ready
在我的 Jasmine 测试中,我使用代表页面各个提取部分的 HTML 固定装置来测试这些元素上的 AJAX 交互(我正在运行 jasmine-rails “服务器”版本,您可以在浏览器中查看 Jasmine 测试报告)
当然,问题在于setup()
尝试绑定处理程序的选择器在加载夹具之前不会存在。结果,在 Jasmine 测试中显式触发的事件将不会被夹具中的 DOM 元素拾取,因为绑定该处理程序的函数已经运行$(document).ready
。
如果只有 Jasmine 能以某种方式将调用延迟到$(document).ready
加载装置之后,我会很高兴。但显然不能。
从上面的两个 StackOverflow 问题中,我收集了各种方法来解决这个问题,但都不能令人满意:
将绑定代码复制
setup
到 HTML 固定装置本身中。这是非 DRY 的,几乎可以肯定会导致夹具与现实不同步,而且夹具应该代表不显眼的 JS,因此不能混合代码和标记。setup
在需要它的测试用例中显式调用该函数。这在简单的情况下有效,但如果setup
做非幂等的事情就会失败。在
setup
中,使用类似的东西$(document).on('click', '#someDiv', someHandler)
代替我上面显示的代码。(我在 jQuery 1.10.1 上。)我实际上尝试过,但它不起作用:即使加载的夹具包含匹配的元素#someDiv
,在该元素上触发“点击”也不会导致someHandler
被调用。即使它确实有效,它也很混乱,因为(如果我理解正确的话)this
调用处理程序时的值将反映实际处理事件的元素,不一定是第一次收到它的元素。在
setup
中,使用类似的东西$('#someDiv').live(someHandler)
,但live
在 jQuery 1.7 中已被弃用并在 1.9 中被删除。
我是否还缺少其他一些不需要更改工作代码以适应测试环境并且不需要违反 DRY 的方法?