Javascript 监视jQuery调用的函数';改变';带着安魂曲和茉莉花
我对RequireJS和Jasmine都是新手,所以我在开始设置一些基本测试时遇到了一些问题。我已经找到了很多关于如何将两者结合在一起的信息,并使其发挥作用。然而,我有一个有趣的问题,我似乎无法解决 不幸的是,我不确定解决问题的最佳方法,因此这里有一些代码: main.js:Javascript 监视jQuery调用的函数';改变';带着安魂曲和茉莉花,javascript,jquery,requirejs,jasmine,jasmine-jquery,Javascript,Jquery,Requirejs,Jasmine,Jasmine Jquery,我对RequireJS和Jasmine都是新手,所以我在开始设置一些基本测试时遇到了一些问题。我已经找到了很多关于如何将两者结合在一起的信息,并使其发挥作用。然而,我有一个有趣的问题,我似乎无法解决 不幸的是,我不确定解决问题的最佳方法,因此这里有一些代码: main.js: require(['jquery', 'manipulate'], function($, Manipulate) { var manipulate = new Manipulate; $(document).on
require(['jquery', 'manipulate'], function($, Manipulate) {
var manipulate = new Manipulate;
$(document).on('change', 'td input', function() {
manipulate.pushChange();
});
});
www.js:
define(function() {
function Manipulate() {
//
};
Manipulate.prototype.pushChange = function() {
return true;
};
return Manipulate;
});
expndtw-1.js:
describe('Manipulate', function() {
var manipulate;
beforeEach(function() {
var flag = false;
// Load fixtures into the HTML
loadFixtures('ManipulateFixture.html');
// Require the manipulate.js file
require(['jquery', 'manipulate', 'main'], function(jQuery, Manipulate) {
manipulate = new Manipulate;
// Define any spies
spyOn(manipulate, 'pushChange');
flag = true;
});
// Wait for manipulate.js to load before running tests
waitsFor(function() {
return flag;
});
});
it('should call pushChange after changing a cell', function() {
$('td input').eq(0).trigger('change');
expect(manipulate.pushChange).toHaveBeenCalled();
});
});
(删除了一些额外的代码)
如果Iconsole.log
在operate.pushChange
内,则它正在启动。问题是,被监视的operate
对象与在main.js
文件中作为参数传递的对象不同。因此,在myit()
块中添加Operation.pushChange
会使测试通过
我找到了Backbone.js应用程序的答案,它调用。我不确定是否有类似的解决方案用于vanilla Javascript、jQuery等,但我找不到
是否有更好的方法来构造文件,将jQuery事件处理程序潜在地放在操纵模块中?或者只是在两个对象之间“复制”事件的一种方法?我甚至不相信在这种情况下使用
createSpy
会对我有多大帮助。您的代码存在一些问题,这使得测试非常困难。首先,如果您想模拟依赖项,就不能像您尝试的那样测试requirerejs模块。看看这个,可以找到一些解决方案
另一个问题是依赖jquery和DOM事件。因此,大多数时候,我不会尝试使用测试装置重建DOM。相反,我监视事件绑定到的jquery对象,并自己调用该函数。因此,请输入您的代码
$(document).on('change', 'td input', function() {
manipulate.pushChange();
});
你可以像这样监视$
var documentSpy ={on:jasmine.createSpy()};
spyOn(window, "$").andReturn(event); // in a requireJs module mock it like in the SO I've mention above
现在,当您的代码绑定事件时,它将只调用spy,您可以检查事件是否正确绑定:
var callback = documentSpy.on.mostRecentCall.args[2]
expect(documentSpy.on).toHasBeenCalledWith('change', 'td input', callback);
// fire the callback
callback();
expect(manipulate.pushChange).toHaveBeenCalled();
我想你部分回答了你自己的问题。您没有对当前正在测试的
operate
实例执行操作。我看到了两种不同的方法来解决这个问题:1)考虑“<代码>操作< /代码>是否是一个“静态”对象,而不是一个“经典”对象的原型。实例化操纵会给你买什么吗?e、 g.-var-operate={pushChange:function(){return true;}}代码>2)找出一种将实际被测对象注入jQuery事件处理程序的好方法。我还要补充一点,我不确定主干。这里的View#delegateEvents
是完全一致的。在主干网中,您可以调用this.delegateEvents
,手动连接视图的events
散列中声明的所有事件。此外,jQuery是主干的可选依赖项。因此,如果主干网看到$
是jQuery
,那么它将使用jQuery的API在视图中连接DOM事件,而不是通过其他方式。我知道这并没有真正解决你问题的根源,只是关于主干如何工作的额外花絮而已。:)我最初编写它是为了有一个“构造函数”,以便在那里定义我的事件侦听器(忘记将它从main.js移到那里)。我去掉了它,使它成为一个对象,带有一个initialize
函数,我可以在需要附加事件时调用它。很有意思。我已经研究过了,但到目前为止还没有什么理由这么做。我最后用了你大部分的答案,但我没能让这些模拟起作用。因此,我没有使用createSpy
来监视.on()
调用,而是直接监视$.fn.on
。但除此之外,要测试的其余代码工作得非常出色。谢谢你的帮助!我的最后一个完整测试:啊,很高兴知道它将以这种方式工作。谢谢你的发现。