单元测试 – 如何在使用RequireJS(和Jasmine / Sinon)时在另一个视图渲染方法中实例化存根骨干视图

我正在尝试使用Jasmine和Sion编写单元测试,但在使用RequireJs加载模块时,我很难找到相当于以下内容:

sinon.stub(window, "MyItemView");

使用RequireJs时,我无法以这种方式存根,因为MyItemView没有附加到窗口.

以下是我需要存根MyItemView时的示例:

var MyView = Backbone.View.extend({
el: '#myElement',
initialize : function() {
    var that = this;
    this.collection.fetch({
        success : function() {
            that.render();
        }
    });
},

render : function() {
    this.collection.each(this.renderItem);
}

renderItem: function(model){
        var myItemView = new MyItemView({model: model});
        $('#myElement').append(myItemView.render().el);
    },

...

现在,使用Jasmine我可以测试innerHtml是否包含预期的HTML:

it('View should contain correct Html', function(){
            var collectionFetchStub = sinon.stub(this.myCollection, 'fetch').yieldsTo('success', this.myCollection);
            this.view = new MyView({collection: this.myCollection});
            expect(this.view.el.innerHTML).toContain('<li><a href=""> 1 : test </a></li>');

            // Remove Stubs
            collectionFetchStub.restore();
        });

但是,此测试依赖于MyItemView的呈现,这对于单元测试来说并不理想.这个问题的最佳解决方案是什么?我是javascript的新手,对此的解决方案似乎很复杂.

最佳答案 看一下
this SO关于如何使用requireJS存根依赖关系.有一些解决方案.像testrJs,squireJs或我自己的小解决方案.主要思想是使用spy / stub / mock覆盖requireJs依赖关系,以便只测试模块.

所以在你的情况下你可以像这样存根MyItemView:

var el = $("<div>test</div>")
var MyItemView = sinon.stub().returns({render: sinon.stub().returns(el)})

然后你必须将MyItemView存根注入你的require上下文,你可以测试测试div被附加到$(‘#myElement’).这并不理想,导致所有DOM的东西,但它会工作.更好的方法是不要在骨干视图之外呈现某些内容.因此,您可以将一个模拟的el注入到视图中,然后测试模拟的append方法是否被调用.

点赞