我正在为我的Backbone视图/模型/集合编写一些集成测试。当我在render
上调用View
时,它只是将模板呈现给它自己的el
属性,因此html只是存储在内存中而不是存储在页面上。下面是一个简单的模型,以及一个绑定到DOM元素的click事件的视图:
var model = Backbone.Model.extend({
urlRoot: '/api/model'
});
var view = Backbone.View.extend({
events: {
'click #remove': 'remove'
}
render: function () {
var html = _.template(this.template, this.model.toJSON());
this.$el.html(html);
},
remove: function () {
this.model.destroy();
}
});
我正在使用Jasmine编写测试。在下面的测试中,我想做的就是监视remove
函数,看看当我为传递给视图的模板中出现的元素#remove
触发click事件时是否调用它
// template
<script id="tmpl">
<input type="button" value="remove" id="remove"/>
</script>
// test
describe('view', function () {
var view;
beforeEach(function () {
view = new view({
template: $('#tmpl').html(),
model: new model()
});
});
it('should call remove when #remove click event fired', function () {
view.$('#remove').click();
var ajax = mostRecentAjaxRequest();
expect(ajax.url).toBe('/api/model');
expect(ajax.method).toBe('DELETE');
});
});
但是,由于#remove
元素在内存中,并且实际上没有添加到DOM中,我不确定如何模拟click事件。事实上,我甚至不确定它是否可能?
在测试中想要这样做似乎有点奇怪,但是我的测试我试图测试行为而不是实现,这样我不关心中间发生的事情 - 我只想测试一下,如果用户点击#remove
,DELETE
请求会被发送回服务器。
答案 0 :(得分:0)
在我看来,您忘了在render()
按钮之前在视图上致电click()
。并且模型需要id
或者主干不会实际尝试对服务器进行删除调用。我之前已经测试了大量的观点而没有任何问题。
我刚刚针对jasmine 2.0和jasmine-ajax 2.0进行了类似的测试。
直播代码:
var MyModel = Backbone.Model.extend({
urlRoot: '/api/model'
});
var MyView = Backbone.View.extend({
events: {
'click #remove': 'remove'
},
initialize: function(options) {
this.template = options.template;
},
render: function () {
var html = _.template(this.template, this.model.toJSON());
this.$el.html(html);
},
remove: function () {
this.model.destroy();
}
});
规格:
describe("testing", function() {
var view;
beforeEach(function() {
jasmine.Ajax.install();
view = new MyView({
template: '<input type="button" value="remove" id="remove"/>',
model: new MyModel({id: 123})
});
view.render();
});
it('should call remove when #remove click event fired', function () {
view.$('#remove').click();
var ajax = jasmine.Ajax.requests.mostRecent();
expect(ajax.url).toBe('/api/model/123');
expect(ajax.method).toBe('DELETE');
});
});