問題描述
我正在使用 Jasmin、Simon 和 jasmin-simon 測試主干視圖.
I'm testing a backbone view with Jasmin, Simon and jasmin-simon.
代碼如下:
var MessageContainerView = Backbone.View.extend({
id: 'messages',
initialize: function() {
this.collection.bind('add', this.addMessage, this);
},
render: function( event ) {
this.collection.each(this.addMessage);
return this;
},
addMessage: function( message ) {
console.log('addMessage called', message);
var view = new MessageView({model: message});
$('#' + this.id).append(view.render().el);
}
});
實際上,我所有的測試都通過了,但只有一個.我想檢查是否在向 this.collection
添加項目時調用了 addMessage
.
Actually, all my tests pass but one. I would like to check that addMessage
is called whenever I add an item to this.collection
.
describe('Message Container tests', function(){
beforeEach(function(){
this.messageView = new Backbone.View;
this.messageViewStub = sinon.stub(window, 'MessageView').returns(this.messageView);
this.message1 = new Backbone.Model({message: 'message1', type:'error'});
this.message2 = new Backbone.Model({message: 'message2', type:'success'});
this.messages = new Backbone.Collection([
this.message1, this.message2
]);
this.view = new MessageContainerView({ collection: this.messages });
this.view.render();
this.eventSpy = sinon.spy(this.view, 'addMessage');
this.renderSpy = sinon.spy(this.messageView, 'render');
setFixtures('<div id="messages"></div>');
});
afterEach(function(){
this.messageViewStub.restore();
this.eventSpy.restore();
});
it('check addMessage call', function(){
var message = new Backbone.Model({message: 'newmessage', type:'success'});
this.messages.add(message);
// TODO: this fails not being called at all
expect(this.view.addMessage).toHaveBeenCalledOnce();
// TODO: this fails similarly
expect(this.view.addMessage).toHaveBeenCalledWith(message, 'Expected to have been called with `message`');
// these pass
expect(this.messageView.render).toHaveBeenCalledOnce();
expect($('#messages').children().length).toEqual(1);
});
});
如您所見,確實調用了 addMessage
.(它會登錄到控制臺并按應有的方式調用 this.messageView
.在監視 addMessage
調用時我錯過了什么?
As you can see addMessage
is called indeed. (It logs to the console and it calls this.messageView
as it should. What do I miss in spying for addMessage
calls?
謝謝,維克托
推薦答案
我不確定,但據我了解,會發生以下情況:
I'm not quit sure but, as I understand it, the following happens:
- 您創建一個調用
initialize
函數的新視圖,并將您的view.addMessage
綁定到您的集合. - 執行此操作后,Backbone 獲取該函數并將其存儲在您集合的事件存儲中.
- 然后你監視
view.addMessage
這意味著你用一個監視函數覆蓋它.這樣做不會影響收集事件存儲中存儲的函數.
- You create a new view which calls the
initialize
function and bind yourview.addMessage
to your collection. - Doing this, Backbone take the function and store it in the event store of your collection.
- Then you spy on
view.addMessage
which means you overwrite it with a spy function. Doing this will have no effect on the function that is stored in the collection event store.
所以他們的測試存在一些問題.您的視圖有很多您沒有模擬出來的依賴項.您創建了一堆額外的 Backbone 模型和集合,這意味著您不僅要測試您的視圖,還要測試 Backbones 集合和模型的功能.
So their are some problems with your test. You view has a lot of dependencies that you not mock out. You create a bunch of additional Backbone Models and Collections, which means you not test only your view but also Backbones Collection and Model functionality.
您不應該測試 collection.bind
是否可以工作,而是您已經使用參數 'add', this.addMessage 對集合調用了
bind
, 這個
You should not test that collection.bind
will work, but that you have called bind
on the collection with the parameters 'add', this.addMessage, this
initialize: function() {
//you dont
this.collection.bind('add', this.addMessage, this);
},
所以,模擬集合很容易:
So, its easy to mock the collection:
var messages = {bind:function(){}, each:function(){}}
spyOn(messages, 'bind');
spyOn(messages, 'each');
this.view = new MessageContainerView({ collection: messages });
expect(message.bind).toHaveBeenCalledWith('bind', this.view.addMessage, this.view);
this.view.render()
expect(message.each).toHaveBeenCalledWith(this.view.addMessage);
... and so on
這樣做你只測試你的代碼,而不依賴于 Backbone.
Doing it this way you test only your code and have not dependencies to Backbone.
這篇關于Sinon 似乎沒有監視事件處理程序回調的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!