[gist]BDD using jasmine jquery

文章详细介绍了使用Jasmine-JQuery进行行为驱动开发(BDD)时遇到的问题,特别是如何解决在fixture中绑定事件后无法触发的问题,并提供了一个热修复方案。通过将需要测试的JavaScript代码放入其依赖的fixture中,并在加载fixture时内联script,解决了事件绑定失败的问题。

from http://oyanglul.us

用 jasmine-jquery 来BDD 就是一个bug, 一个大bug

参加 TWU 时写 jasmine 测试的时候花了大量时间研究为什么不能绑定事件到 fixture. 这导致 teamate 和我自己都会认为我这个带头引入这么难用的 jasmine 的人简直是要杀千刀. 但是其实问题不是 jasmine 当然也不是我, 都是 jasmine-jquery

不管是 loadfixtures 还是 preload(fixtureUrl[, fixtureUrl, …]) 都无法 绑定事件到 fixtures

BDD 不就是想要点哪然后看哪得反应…结果不知道为什么傻傻的就没有反应.

傻兮兮的官方文档是这样的

var spyEvent = spyOnEvent('#some_element', 'click')
$('#some_element').click()
expect('click').toHaveBeenTriggeredOn('#some_element')

这…不是废话么….这是在测试”测试代码”么?

真正关心测试的应该是绑定在click事件上的function, 谁管你被tri没 trigger. 比如我在元素 #anchor_01 上绑定了添加 css class 的事件.那么我 应该这样测试我的 javascript 代码.

describe("when fixture contains an <script src='to/your/source'> tag", function () {
  var fixtureUrl = "fixture_with_javascript.html"

  it("should load content of fixture file and javascripts and bind events", function () {
    jasmine.getFixtures().load(fixtureUrl)
    $('#anchor_01').click()
    expect($("#anchor_01")).toHaveClass('foo')
  })
})

但是这样的 test 是会 fail 掉…

原因在于包含绑定事件的 script 在 specRunner.html 加载时就已经被load了.即 时你用的时 $() wrapper, 因为 specRunner.html 的 document 在运行你的 **spec.js 时已经是ready的了

也就是说这时候并没有loadFixtures, script 中的事件不会绑定到元素上, 除 非你用的时live…

what do we do

之前一个项目也碰到过类似的情况, 当时的 OO 得比较好, 可以在loadFixtures 之后再 init 一下需要测试的类. 但是那些不OO的代码肿么办

事实上我认为 fixture 应该是业务逻辑的一个片段, 那么将需要绑定事件到 fixture 的 script 扔到 fixture 比较 make sense 因为他们本来就是紧耦合.

因此我的 hot fix 是将需要测试的 js 放到它所依赖的 fixtrue 里面, 之后在 loadFixtures 时将 script inline 到 fixture 中然后加载到 specRunner 页 面上.

diff --git a/lib/jasmine-jquery.js b/lib/jasmine-jquery.js
index 87d7ef8..30d12db 100644
--- a/lib/jasmine-jquery.js
+++ b/lib/jasmine-jquery.js
@@ -119,17 +119,33 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFT
WARE.
   jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
     var self = this
       , url = this.makeFixtureUrl_(relativeUrl)
+      , htmlText = ''
       , request = $.ajax({
         async: false, // must be synchronous to guarantee that no tests are run
 before fixture is loaded
         cache: false,
         url: url,
         success: function (data, status, $xhr) {
-          self.fixturesCache_[relativeUrl] = $xhr.responseText
+          htmlText = $xhr.responseText
         },
         error: function (jqXHR, status, errorThrown) {
           throw new Error('Fixture could not be loaded: ' + url + ' (status: '
+ status + ', message: ' + errorThrown.message + ')')
         }
       })
+      var scripts = $($.parseHTML(htmlText, true)).find('script') || [];
+      scripts.each(function(){
+        $.ajax({
+            async: false, // must be synchronous to guarantee that no tests are
 run before fixture is loaded
+            cache: false,
+            url: $(this).attr('src'),
+            success: function (data, status, $xhr) {
+                htmlText += '<script>' + $xhr.responseText + '</script>'
+            },
+            error: function (jqXHR, status, errorThrown) {
+                throw new Error('Script could not be loaded: ' + scriptSrc + '
(status: ' + status + ', message: ' + errorThrown.message + ')')
+            }
+        });
+      })
+      self.fixturesCache_[relativeUrl] = htmlText;
   }

   jasmine.Fixtures.prototype.makeFixtureUrl_ = function (relativeUrl){

这样用起来会比较简单, 只需要在fixture里面加入 script 即可

<div id="anchor_01"></div>
<script src="spec/fixtures/javascripts/jasmine_javascript_c
lick.js"></script>
<script src="spec/fixtures/javascripts/jasmine_javascript_hove
r.js"></script>

不需要修改任何 jasmine 测试代码, 依然是这段代码, 这是它应该就会 绿

describe("when fixture contains an <script src='to/your/source'> tag", function () {
  var fixtureUrl = "fixture_with_javascript.html"

  it("should load content of fixture file and javascripts and bind events", function () {
    jasmine.getFixtures().load(fixtureUrl)
    $('#anchor_01').click()
    expect($("#anchor_01")).toHaveClass('foo')
  })
})

fin 我已经 pull request 到这里 但是人家木有一点要 merge 的意思…好吧,反正我是不会用了, 要是谁被无法绑定事件困扰就不要再浪费时间困扰了, 可以 clone 我的 fork 吧 亲.

view raw 2013-11-27-bdd-using-jasmine-jquery.org hosted with ? by GitHub
先看效果: https://renmaiwang.cn/s/jkhfz Hue系列产品将具备高度的个性化定制能力,并且借助内置红、蓝、绿三原色LED的灯泡,能够混合生成1600万种不同色彩的灯光。 整个操作流程完全由安装于iPhone上的应用程序进行管理。 这一创新举措为智能照明控制领域带来了新的启示,国内相关领域的从业者也积极投身于相关研究。 鉴于Hue产品采用WiFi无线连接方式,而国内WiFi网络尚未全面覆盖,本研究选择应用更为普及的蓝牙技术,通过手机蓝牙与单片机进行数据交互,进而产生可调节占空比的PWM信号,以此来控制LED驱动电路,实现LED的调光功能以及DIY调色方案。 本文重点阐述了一种基于手机蓝牙通信的LED灯设计方案,该方案受到飞利浦Hue智能灯泡的启发,但考虑到国内WiFi网络的覆盖限制,故而选用更为通用的蓝牙技术。 以下为相关技术细节的详尽介绍:1. **智能照明控制系统**:智能照明控制系统允许用户借助手机应用程序实现远程控制照明设备,提供个性化的调光及色彩调整功能。 飞利浦Hue作为行业领先者,通过红、蓝、绿三原色LED的混合,能够呈现1600万种颜色,实现了全面的定制化体验。 2. **蓝牙通信技术**:蓝牙技术是一种低成本、短距离的无线传输方案,工作于2.4GHz ISM频段,具备即插即用和强抗干扰能力。 蓝牙协议栈由硬件层和软件层构成,提供通用访问Profile、服务发现应用Profile以及串口Profiles等丰富功能,确保不同设备间的良好互操作性。 3. **脉冲宽度调制调光**:脉冲宽度调制(PWM)是一种高效能的调光方式,通过调节脉冲宽度来控制LED的亮度。 当PWM频率超过200Hz时,人眼无法察觉明显的闪烁现象。 占空比指的...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值