9

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

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 视图对象的渲染函数。

观点是:

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();
        }
    });   
});

间谍检测到调用是在上述情况下进行的。

有谁知道为什么间谍在我的初始测试中没有识别渲染调用?

4

3 回答 3

25

问题是在视图的构建过程中,初始化函数将一个事件直接绑定到渲染函数。您不能使用间谍拦截此事件,因为在您设置间谍之前绑定已经发生(您在构建之后执行)。

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

要设置间谍:

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

稍后,要删除间谍:

ProfileView.prototype.render.restore()

然后,这将监视对渲染的“普通”调用,以及来自模型的更改事件。

于 2012-04-24T16:10:48.207 回答
3

仅 3 种猜测:

  1. 您假设在更新并触发模型事件fetch({ success })之后调用回调Model..并且可能不是这样。解决方法:尝试在这里玩调试
  2. 也许fetch调用不成功,所以不调用成功回调。解决方案:尝试向 中添加错误回调fetch看看是否有我们被发送到的地方。
  3. Model.validate响应false,如果您尚未实施,则不太可能发生。

(我赌2。

于 2012-03-14T14:27:00.800 回答
0

这对我有用,尽管在集合中使用了间谍:

var thatzzz = this;
    this.hcns.fetch({
        success: function(){
            expect( thatzzz.hcnsFetchSpy ).toHaveBeenCalled();
        }
});
  • 间谍是在 beforeEach 上定义的
于 2012-03-28T16:17:45.403 回答