用 Sinon.js 模拟的对象不承认它们的方法通过 jQuery.delegate 回调执行

Posted

技术标签:

【中文标题】用 Sinon.js 模拟的对象不承认它们的方法通过 jQuery.delegate 回调执行【英文标题】:Objects mocked with Sinon.js do not acknowledge having their methods executed via a jQuery.delegate callback 【发布时间】:2012-04-09 08:47:20 【问题描述】:

基本上,如果您使用 Sinon.js 模拟对象,该对象具有作为回调传递给 jQuery.delegate 的属性,当您触发在 jQuery.delegate 中观察的方法时,您的模拟期望将失败。如果您在用作 jQUery.delegate 回调的匿名函数主体内执行该方法,您的期望就会通过。

test("FAILS: 处理程序作为回调直接从 jQuery 委托方法调用...", function() var 控制器, 看法, $el, C, 五, 嘲笑; 控制器 = 函数() 变量自我 = ; self.handler = 函数(e) console.log("得到处理"); ; 回归自我; ; 视图 = 函数($el,控制器) 变量自我 = ; self.render = 函数() $el.html(""); $el.delegate("#derp", "keyup", controller.handler); ; 回归自我; ; $el = jQuery(""); c = 新控制器(); v = 新视图($el, c); 模拟 = this.mock(c); v.render(); mock.expects("handler").once(); $el.find("input").val("bar").trigger("keyup"); 相等($el.find(“输入”).val(),“酒吧”); // 通过! 模拟.验证(); ); test("WINS: 处理程序在匿名函数中被调用...", function() var 控制器, 看法, $el, C, 五, 嘲笑; 控制器 = 函数() 变量自我 = ; self.handler = 函数(e) console.log("得到处理"); ; 回归自我; ; 视图 = 函数($el,控制器) 变量自我 = ; self.render = 函数() $el.html(""); $el.delegate("#derp", "keyup", function(e) 控制器.handler(e); ); ; 回归自我; ; $el = jQuery(""); c = 新控制器(); v = 新视图($el, c); 模拟 = this.mock(c); v.render(); mock.expects("handler").once(); $el.find("input").val("bar").trigger("keyup"); 相等($el.find(“输入”).val(),“酒吧”); // 通过! 模拟.验证(); );

我在这里做错了吗?

谢谢,

艾琳

【问题讨论】:

必须同意,如果 v2 有效,那么 v1 也应如此。 v1 是否也会因实际键入而失败?使用.triggerHandler("keyup") 进行测试时,v1 是否也会失败? 【参考方案1】:

这是一个经典的callback scope 陷阱。函数参数超出范围,因此 controller 没有 handler 方法,因为它没有在本地定义。匿名函数赋予它作用域,因为函数控制 javascript 中的作用域。

【讨论】:

以上是关于用 Sinon.js 模拟的对象不承认它们的方法通过 jQuery.delegate 回调执行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sinon js/loopback testlab 模拟来自 twilio-node 的 messages.create() 方法的返回值?

Sinon 窥探 WebSocket

模拟对象的目的是啥?

如何在 JavaScript 单元测试中模拟 localStorage?

使用 FakeItEasy 的私有方法和属性的单元测试用例 [重复]

将深层链接传递到 iOS 模拟器?