我对RequireJS和Jasmine都很陌生,所以我在设置几个基本测试时遇到了一些麻烦。我已经找到了很多关于如何将两者设置在一起的信息,并让它工作。但是我有一个我似乎无法解决的有趣问题。
不幸的是,我不确定解决问题的最佳方法,所以这里有一些代码:
main.js:
require(['jquery', 'manipulate'], function($, Manipulate) {
var manipulate = new Manipulate;
$(document).on('change', 'td input', function() {
manipulate.pushChange();
});
});
manipulate.js:
define(function() {
function Manipulate() {
//
};
Manipulate.prototype.pushChange = function() {
return true;
};
return Manipulate;
});
ManipulateSpec.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();
});
});
(删除了一些额外的代码)
如果我在console.log
内Manipulate.pushChange
,它就会被解雇。问题是,正在监视的Manipulate
对象与main.js
文件中作为参数传递的对象不同。因此,在manipulate.pushChange
块中添加it()
会使测试通过。
我找到了Backbone.js应用程序的答案,该应用程序调用了delegateEvents
。我不确定是否有类似于vanilla Javascript,jQuery等的解决方案,但我找不到。
有没有更好的方法来构建我的文件,可能会将我的jQuery事件处理程序放在操作模块中?或者只是一种在两个对象之间“复制”事件的方法?在这种情况下,我甚至不相信使用createSpy
会对我有所帮助。
答案 0 :(得分:2)
您的代码存在一些问题,导致测试非常困难。首先,如果您想模拟依赖项,则无法像尝试它一样测试requiereJs模块。请查看此SO以获取一些解决方案。
另一个问题是你在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
现在,当您的代码绑定事件时,它只会调用间谍,您可以检查事件是否绑定正确:
var callback = documentSpy.on.mostRecentCall.args[2]
expect(documentSpy.on).toHasBeenCalledWith('change', 'td input', callback);
// fire the callback
callback();
expect(manipulate.pushChange).toHaveBeenCalled();