Aka*_*sha 5 javascript testing jasmine sinon
我正在用Jasmin,Simon和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);
}
});
Run Code Online (Sandbox Code Playgroud)
实际上,我的所有测试都通过了一次.addMessage每当我添加一个项目时,我想检查是否被调用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);
});
});
Run Code Online (Sandbox Code Playgroud)
你可以看到addMessage确实被称为.(它记录到控制台,它this.messageView应该调用它.我在间谍addMessage电话中错过了什么?
谢谢,维克多
我不确定,但据我了解,发生以下情况:
initialize函数并将您绑定view.addMessage到您的集合.view.addMessage哪个意味着你用间谍功能覆盖它.执行此操作不会影响存储在集合事件存储中的函数.所以他们的测试存在一些问题.你认为有很多依赖,你没有嘲笑.您创建了一堆额外的Backbone模型和集合,这意味着您不仅可以测试您的视图,还可以测试Backbones集合和模型功能.
你不应该测试它collection.bind会起作用,但是你已经bind使用参数调用了集合'add', this.addMessage, this
initialize: function() {
//you dont
this.collection.bind('add', this.addMessage, this);
},
Run Code Online (Sandbox Code Playgroud)
所以,它很容易模拟集合:
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
Run Code Online (Sandbox Code Playgroud)
这样做只需要测试代码并且不依赖于Backbone.
正如安德烈亚斯在第3点所说:
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.
这个问题的直接答案,无视安德烈亚斯建议的所有令人敬畏的重构,都会MessageContainerView.prototype.addMessage像这样窥探:
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
]);
// Here
this.addMessageSpy = sinon.spy(MessageContainerView.prototype, 'addMessage');
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();
MessageContainerView.prototype.addMessage.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.addMessageSpy).toHaveBeenCalledOnce();
// TODO: this fails similarly
expect(this.addMessageSpy).toHaveBeenCalledWith(message, 'Expected to have been called with `message`');
// these pass
expect(this.messageView.render).toHaveBeenCalledOnce();
expect($('#messages').children().length).toEqual(1);
});
});
Run Code Online (Sandbox Code Playgroud)
无论如何,我建议实施Andreas的建议.:)
| 归档时间: |
|
| 查看次数: |
4002 次 |
| 最近记录: |