0

我正在为我的 Backbone 视图/模型/集合编写一些集成测试。当我调用rendermyView时,它只是将模板呈现给它自己的el属性,因此 html 只是存储在内存中而不是页面上。下面是一个简单的模型,以及一个带有绑定到 DOM 元素的点击事件的视图:

var model = Backbone.Model.extend({
    urlRoot: '/api/model'
});

var view = Backbone.View.extend({
    events: {
        'click #remove': 'remove'
    }
    render: function () {
        var html = _.template(this.template, this.model.toJSON());
        this.$el.html(html);
    },
    remove: function () {
        this.model.destroy();
    }
});

我正在使用 Jasmine 编写测试。在下面的测试中,我要做的就是监视该函数,以查看在为我传递给视图的模板中存在remove的元素触发 click 事件时是否调用它。#remove

// template

<script id="tmpl">
    <input type="button" value="remove" id="remove"/>
</script>

// test

describe('view', function () {

    var view;

    beforeEach(function () {
        view = new view({
            template: $('#tmpl').html(),
            model: new model()
        });
    });

    it('should call remove when #remove click event fired', function () {       
        view.$('#remove').click();

        var ajax = mostRecentAjaxRequest();
        expect(ajax.url).toBe('/api/model');
        expect(ajax.method).toBe('DELETE');
    });

});

但是,由于该#remove元素在内存中,并且实际上并未添加到 DOM 中,因此我不确定您将如何模拟单击事件。事实上,我什至不确定这是否可能?

想要在测试中执行此操作似乎有点奇怪,但是通过我的测试,我试图测试行为而不是实现,这样我就不关心两者之间发生了什么——我只想测试一下,如果用户点击#remove一个DELETE请求被发送回服务器。

4

1 回答 1

0

在我看来,您好像忘记在按钮render()之前调用视图。click()并且模型需要有一个id或主干实际上不会尝试对服务器进行删除调用。我之前已经测试过很多这样的视图,没有任何问题。

我刚刚对 jasmine 2.0 和 jasmine-ajax 2.0 进行了类似的测试。

实时代码:

var MyModel = Backbone.Model.extend({
  urlRoot: '/api/model'
});

var MyView = Backbone.View.extend({
  events: {
    'click #remove': 'remove'
  },
  initialize: function(options) {
    this.template = options.template;
  },
  render: function () {
    var html = _.template(this.template, this.model.toJSON());
    this.$el.html(html);
  },
  remove: function () {
    this.model.destroy();
  }
});

眼镜:

describe("testing", function() {
  var view;

  beforeEach(function() {
    jasmine.Ajax.install();
    view = new MyView({
      template: '<input type="button" value="remove" id="remove"/>',
      model: new MyModel({id: 123})
    });
    view.render();
  });

  it('should call remove when #remove click event fired', function () {
    view.$('#remove').click();

    var ajax = jasmine.Ajax.requests.mostRecent();
    expect(ajax.url).toBe('/api/model/123');
    expect(ajax.method).toBe('DELETE');
  });
});
于 2014-01-26T20:30:05.847 回答