2

我正在使用backbone.validation来验证我的主干模型,并在我的工作中采用了TDD 方法。不幸的是,在测试实际需要的字段时,我似乎无法调用我的间谍。

我一直在关注使用 Jasmine 和 Sinon 测试 Backbone 应用程序的教程, 除非他"error""invalid". 这样做的原因是因为我认为backbone.validation 使用了无效/有效回调,而不是如自述文件的事件部分所述。

我的问题是我收到错误消息说我的间谍从未被调用。我尝试将绑定更改回错误/保存,但仍然没有运气。

我的代码如下:

class Event extends Backbone.Model
    url: ->
      '/events' + (if @isNew() then '' else '/' + @id)

    validation:
      title:
        required: true
      start_date:
        required: true
      end_date:
        required: true
      description:
        required: true

然后我定义一个测试如下:

describe "Event", ->
  beforeEach ->
    @title = "Foo"
    @description = "Bar"
    @start_date = new Date
    @end_date = new Date


    @event = new CPP.Models.Event {
      title: @title
      description: @description
      start_date: @start_date
      end_date: @end_date
    }

  describe "when saving required fields", ->
    beforeEach ->
      @error_spy = sinon.spy();
      @event.bind('invalid', @error_spy)

    it "should not save when title is empty", ->
      @event.save 'title': ""
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when start_date is empty", ->
      @event.save 'start_date': ""
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when end_date is empty", ->
      @event.save 'end_date': ""l
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when description is empty", ->
      @event.save 'description': ""
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when location is empty", ->
      @event.save 'location': null
      expect(@error_spy).toHaveBeenCalledOnce();

  describe "when saving optional fields", ->
    beforeEach ->
      @success_spy = sinon.spy();
      @event.bind('valid', @success_spy)

    it "should save when deadline is empty", ->
      @event.save 'deadline': ""
      expect(@success_spy).toHaveBeenCalledOnce();

然而,当我运行我的测试时,我似乎得到Error: Expected Function to have been called once.了所有这些,并且在进一步检查 @event 对象时,我发现从未调用过间谍。

我认为这可能与通过 _.extend(Backbone.Model.prototype, Backbone.Validation.mixin);骨干网.validation自述文件中定义的模型原型的验证混合有关,但我似乎也无法让它工作。

我看过这个问题,为什么在我运行这个测试时没有调用这个 sinon 间谍?但是,我也没有将答案合并到我的代码中。

如果有人能告诉我我做错了什么,我将不胜感激!

已修复 我设法修复我的代码如下:(1)我添加_.extend Backbone.Model::, Backbone.Validation.mixin到我的应用程序中

(2) 然后我按照这个问题中给出的建议在初始化时绑定我的间谍。代码现在如下所示: 模型:class Event extends Backbone.Model url: -> '/events' + (if @isNew() then '' else '/' + @id)

    validation:
      title:
        required: true
      start_date:
        required: true
      end_date:
        required: true
      description:
        required: true

考试:

describe "Event", ->
  beforeEach ->
    @title = "Foo"
    @description = "Bar"
    @start_date = new Date
    @end_date = new Date

  describe "when saving required fields", ->
    beforeEach ->
      spy = @error_spy = sinon.spy();
      init = CPP.Models.Event::initialize
      CPP.Models.Event::initialize = ->
        spy(@, "validated:invalid")
        init.call this

      @event = new CPP.Models.Event {
        title: @title
        description: @description
        location: @location
        start_date: @start_date
        end_date: @end_date
      }

    it "should not save when title is empty", ->
      @event.save 'title': ""
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when start_date is empty", ->
      @event.save 'start_date': ""
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when end_date is empty", ->
      @event.save 'end_date': ""l
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when description is empty", ->
      @event.save 'description': ""
      expect(@error_spy).toHaveBeenCalledOnce();

    it "should not save when location is empty", ->
      @event.save 'location': null
      expect(@error_spy).toHaveBeenCalledOnce();

  describe "when saving optional fields", ->

    beforeEach ->
      spy = @success_spy = sinon.spy();
      init = CPP.Models.Event::initialize
      CPP.Models.Event::initialize = ->
        spy(@, "validated:valid")
        init.call this

      @event = new CPP.Models.Event {
        title: @title
        description: @description
        location: @location
        start_date: @start_date
        end_date: @end_date
      }

    it "should save when deadline is empty", ->
      @event.save 'deadline': ""
      expect(@success_spy).toHaveBeenCalledOnce();
4

2 回答 2

2

您是否检查过您是否包含添加验证混合的代码?

如果您希望能够在整个应用程序中绑定到模型中的已验证事件,而不是绑定到特定视图,那么您需要通过编写来添加 mixin

_.extend(Backbone.Model.prototype, Backbone.Validation.mixin)

可以使用 coffeescript 在您的应用程序中编写

_.extend Backbone.Model::, Backbone.Validation.mixin

将此代码添加到您的主 Backbone 应用程序文件中。

完成此操作后,您的间谍问题可能与此问题相关联- 您需要在绑定任何事件处理程序之前检查您是否在正确的时间绑定了间谍。上一个链接中的解决方案是通过挂钩初始化来实现的。

于 2012-11-05T19:59:39.237 回答
0

我认为您只是绑定到错误的事件。来自精美手册

已验证

validated事件在执行验证后触发,无论是否成功。isValidtruefalse取决于验证的结果。

model.bind('validated', function(isValid, model, errors) {
  // do something
});

验证:有效

validated:valid执行成功验证后触发该事件。

model.bind('validated:valid', function(model) {
  // do something
});

已验证:无效

validated:invalid在执行不成功的验证后触发该事件。

model.bind('validated:invalid', function(model, errors) {
  // do something
});

所以没有'invalid'事件,但有'validated:invalid'事件。试试这个:

@event.bind('validated:invalid', @error_spy)
于 2012-11-04T06:22:52.450 回答