我正在爲我的Backbone views/models/collections編寫一些集成測試。當我在我的View
上調用render
時,它只是將模板呈現給它自己的el
屬性,因此該html僅存儲在內存中而不是頁面上。下面是一個簡單的模型,並與結合在一個DOM元素的click事件的看法:當測試Backbone Views時在內存中的元素上觸發事件
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();
}
});
我使用茉莉來寫我的測試。在下面的測試中,我想要做的就是窺探remove
函數,看看它是否在點擊事件觸發元素#remove
時被調用,該元素存在於傳遞給視圖的模板中。
// 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,我不知道你將如何模擬點擊事件。事實上,我甚至不確定是否有可能?
這似乎有點奇怪想這樣做的測試,但我的測試,我想測試行爲而不是實施,這樣一來我不關心什麼之間發生的 - 我只想測試,如果用戶點擊#remove
a DELETE
請求被髮送回服務器。
你確定的問題是,'從視圖remove'方法不會被調用?我創建了[demo](http://jsbin.com/ihabom/2/edit),我只在內存中調用'click',它按預期工作。你在瀏覽器環境或phantom.js中運行測試嗎? – dreame4
FWIW,爲了測試對服務器的請求,我建議使用[sinon.js](http://sinonjs.org/docs/)來模擬它。它有一個你可以設置的假服務器。它應該比實際讓代碼在單元測試期間發送真正的AJAX請求更快(並且更安全?)。 –
@DaveNichol它看起來像我使用[jasmine-ajax](https://github.com/pivotal/jasmine-ajax)去除ajax請求,所以沒有實際的請求正在進行。這就是'mostRecentAjaxRequest'調用的目的 – Gregg