Backbone.js在浏览器中使用Sinon Spies查看测试

时间:2012-03-08 19:56:58

标签: javascript backbone.js mocha sinon

我正在为Backbone View编写测试,以测试在获取模型后是否正在调用render函数。测试是:

beforeEach(function () {
    $('body').append('<div class="sidebar"></div>');
    profileView = new ProfileView();
});

it('should call the render function after the model has been fetched', function (done) {
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'});
    var spy = sinon.spy(profileView, 'render');
    profileView.model.fetch({
        success: function () {
            sinon.assert.called(spy);
            done();
        }
    });   
});

我正在使用Sinon Spies将间谍对象附加到profileView视图对象的render函数。

观点是:

var ProfileView = Backbone.View.extend({
    el: '.sidebar'
  , template: Hogan.compile(ProfileTemplate)
  , model: new UserModel()
  , initialize: function () {
        this.model.bind('change', this.render, this);
        this.model.fetch();
    }
  , render: function () {
        $(this.el).html(this.template.render());
        console.log("Profile Rendered");
        return this;
    }
});

在测试中调用fetch之后,更改事件正在触发,并且调用了视图的渲染函数,但是Sinon Spy没有检测到正在调用渲染并且失败。

作为一项实验,我尝试在测试中调用render函数来查看Spy是否识别出它:

it('should call the render function after the model has been fetched', function (done) {
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'});
    var spy = sinon.spy(profileView, 'render');
    profileView.render();
    profileView.model.fetch({
        success: function () {
            sinon.assert.called(spy);
            done();
        }
    });   
});

间谍检测到被叫是在上面的案例中做出的。

有没有人知道为什么Spy在初始测试中没有识别渲染调用?

3 个答案:

答案 0 :(得分:25)

问题是在构造视图期间,initialize函数将事件直接绑定到render函数。您无法使用间谍拦截此事件,因为在您设置间谍之前已经发生了绑定(您在构建之后就已经进行了绑定)。

解决方案是在构建视图之前监视原型。因此,您必须将间谍移动到beforeEach中,或者将视图的构造移动到测试中。

设置间谍:

this.renderSpy = sinon.spy(ProfileView.prototype, 'render');
this.view = new ProfileView();

然后,去除间谍:

ProfileView.prototype.render.restore()

然后,这会窥探'普通'渲染调用,以及模型中的更改事件。

答案 1 :(得分:3)

只有3个猜测:

  1. 您假设在更新fetch({ success })并触发Model事件后调用了Model回调..可能不是这样的。 解决方案:尝试围绕here进行播放调试
  2. 可能fetch调用不是成功,因此不会调用成功回调。 解决方案:尝试向fetch添加错误回调,看看我们是否在哪里发送。
  3. Model.validate回复false,如果您尚未实施,不太可能
  4. (我打赌 2。

答案 2 :(得分:0)

虽然间谍用于集合中,但这对我有用:

var thatzzz = this;
    this.hcns.fetch({
        success: function(){
            expect( thatzzz.hcnsFetchSpy ).toHaveBeenCalled();
        }
});
  • 间谍是在beforeEach
  • 上定义的