【发布时间】:2015-02-15 08:55:30
【问题描述】:
我正在尝试使用 grunt、karma、jasmine 2 和 chrome 作为输出浏览器来测试我的 Backbone.view。 我的视图正在响应点击事件:
el: $('#wrap'),
events: {
(...)
'click #sender' : 'observeSender',
(...)
},
其中 sender 是菜单栏中的 div(由视图呈现),observeSender() 方法会打开一个 UI 窗口。 我对此的测试:
it('should show error dialog', function() {
var model = new fooModel({ 'config' : config });
var view = new barview({ model: model });
expect($('#errors-dialog').is(':visible')).toBe(false);
sender = $('#wrap').find('div#sender').eq(0);
sender.trigger('click');
expect($('#errors-dialog').is(':visible')).toBe(true);
});
此测试失败。我已经尝试了很多东西,最后,如果我改变我的观点:
events: {
(...)
//'click #sender' : 'observeSender',
(...)
},
initialize: function(options) {
(...)
$('#sender').on('click', function(){ self.observeSender.call(self); });
}
现在测试通过了。第一个示例在尝试实时应用程序时工作正常,但不可测试,第二个选项工作一次,但在重新渲染 #sender 后(由于其他事件)不能工作。我仍然希望以第一种方式组织它,那我做错了什么?
更新 1
按照建议,我将测试中的所有查询都切换到 view.$,但测试仍然失败
expect(view.$('#errors-dialog').is(':visible')).toBe(true);
更新 2
我需要澄清一下,observeSender() 方法负责调出 UI 对话框。它永远不会被调用。我的问题不是关于 DOM 中的元素,它都在那里,我使用 Karma Debug Runner 和 Chrome 控制台来检查它。
如果我用console.log('hello'); 语句替换observeSender 方法的全部内容,我将永远看不到它的输出,使用我定义点击事件“主干方式”的第一种方法。在我看来,在测试期间 事件 发生了一些事情。
更新 3
我已经完成了主干库的测试并复制了a test from their view tests
it('should delegateEvents', function() {
var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '#testElement'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click h1': 'increment'};
view.delegateEvents(events);
view.$('h1').trigger('click');
expect(counter1).toBe(1);
expect(counter2).toBe(1);
view.$('h1').trigger('click');
expect(counter1).toBe(2);
expect(counter2).toBe(2);
view.delegateEvents(events);
view.$('h1').trigger('click');
expect(counter1).toBe(3);
expect(counter2).toBe(3);
});
输出是:
Expected 0 to be 1.
Error: Expected 0 to be 1.
at /.../Spec.js:20572
Expected 0 to be 1.
Error: Expected 0 to be 1.
at /.../Spec.js:20573
Expected 0 to be 2.
Error: Expected 0 to be 2.
at /.../Spec.js:20576
Expected 0 to be 2.
Error: Expected 0 to be 2.
at /.../Spec.js:20577
Expected 0 to be 3.
Error: Expected 0 to be 3.
at /../Spec.js:20581
Expected 0 to be 3.
Error: Expected 0 to be 3.
在 Chrome 和 PhantomJS 中运行它,结果相同,我现在要深入研究 Jasmine...
【问题讨论】:
-
这个视图的
el中的#senderdiv 是否存在? -
是的#wrap就是el,#sender本身是由里面的view渲染的
-
您永远不会将视图附加到 DOM。你为什么期望
$('#errors-dialog')存在?您应该渲染视图,将其附加到 DOM,并使用view.$()来查询元素,而不是使用全局 jQuery 选择器 -
我省略了大部分代码以保持问题较小。我不是在检查#errors-dialog 是否存在,而是在检查它是否可见,因为observeSender 方法负责显示它。在我的测试中,我将#errors-dialog 添加为夹具,在应用程序中它位于主模板中。所有元素都存在并被发现,我相信这与视图的事件无关。
-
使用 Backbone 视图测试,您几乎肯定希望像 Uzi Kilon 所说的那样使用
view.$。如果该应用在现实中运行,这很可能是您的问题。
标签: javascript backbone.js jasmine karma-jasmine