Ruby on rails 使用Backbone.validation测试主干模型验证-间谍永远不会被调用

Ruby on rails 使用Backbone.validation测试主干模型验证-间谍永远不会被调用,ruby-on-rails,validation,backbone.js,coffeescript,jasmine,Ruby On Rails,Validation,Backbone.js,Coffeescript,Jasmine,为了验证我的主干模型,我使用了TDD方法。不幸的是,在测试字段是否确实是必需的时,我似乎无法调用我的spy 我一直在关注关于 除非他把他的间谍注册为“错误”,我已经试着把我的间谍注册为“无效”。这是因为我认为backbone.validation使用无效/有效回调,如自述文件事件部分所述 我的问题是,我说我的间谍从来没有接到过电话,这是错误的。我尝试将绑定更改回error/save,但仍然没有成功 我的代码如下: class Event extends Backbone.Model ur

为了验证我的主干模型,我使用了TDD方法。不幸的是,在测试字段是否确实是必需的时,我似乎无法调用我的spy

我一直在关注关于 除非他把他的间谍注册为“错误”,我已经试着把我的间谍注册为“无效”。这是因为我认为backbone.validation使用无效/有效回调,如自述文件事件部分所述

我的问题是,我说我的间谍从来没有接到过电话,这是错误的。我尝试将绑定更改回error/save,但仍然没有成功

我的代码如下:

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();
然后,我定义了一个测试,如下所示:

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();
然而,当我运行我的测试时,我似乎得到了
错误:预期函数被调用了一次。
对于所有的测试,在进一步检查@event对象时,我发现spy从未被调用过

我认为这可能与混合验证模型的原型有关
\扩展(Backbone.Model.prototype、Backbone.Validation.mixin)如backbone.validation自述文件中所定义,但我似乎也无法实现这一点

我已经看了这个问题,但是我也没有把答案整合到我的代码中

如果有人能告诉我我做错了什么,我将非常感激

固定的 我成功地修复了我的代码,如下所示: (1) 我在我的应用程序中添加了
。.extend-Backbone.Model::,Backbone.Validation.mixin

(2) 然后,我按照中给出的建议将我的间谍绑定到了服务器上。代码现在如下所示: 模型: 类事件扩展了主干.Model 网址:-> '/events'+(如果@isNew(),那么''else'/'+@id)

测试:

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

我认为你只是在与错误的事件绑定。从:

已验证

执行验证后,无论验证是否成功,都会触发
validated
事件
isValid
是否为
true
false
取决于验证结果

model.bind('validated', function(isValid, model, errors) {
  // do something
});
已验证:有效

成功执行验证后,将触发
validated:valid
事件

model.bind('validated:valid', function(model) {
  // do something
});
model.bind('validated:invalid', function(model, errors) {
  // do something
});
已验证:无效

执行不成功的验证后,将触发
validated:invalid
事件

model.bind('validated:valid', function(model) {
  // do something
});
model.bind('validated:invalid', function(model, errors) {
  // do something
});
因此没有
'invalid'
事件,但是有
'validated:invalid'
事件。试试这个:

@event.bind('validated:invalid', @error_spy)

您是否已检查是否包含用于添加验证混合的代码

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

_.extend(Backbone.Model.prototype, Backbone.Validation.mixin)
可以使用coffeescript作为

_.extend Backbone.Model::, Backbone.Validation.mixin
在主主干应用程序文件中添加此代码


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

如果将
@event.bind('invalid',@error\u spy)
更改为
event.prototype.bind('invalid',@error\u spy),该怎么办
?然后我得到错误
对象#没有方法“bind”
很抱歉,如果没有其他人回答,我将稍后详细查看。您不应该绑定
验证:无效
而不是
无效
?我从来没有使用过backbone.validation,只是在阅读似乎是事件名称的文档。我不认为这个问题与将
Backbone.Validation.mixin
混入模型原型有关。如果您正在监视由(已绑定的)事件触发的方法,那么另一个SO答案是相关的,但在这种情况下,您自己正在将一个间谍绑定到一个事件,所以这应该不是问题。我首先尝试了这个,但仍然得到了相同的消息
预期函数被调用过一次。
我将在update@Sarah:您可以尝试将
->console.log(arguments)
绑定到
“all”
事件,以查看触发了什么(如果有)。结果是“error”正在被调用,当我将->console.log“ERROR”绑定到“ERROR”时,它会显示“ERROR”,但当我将spy绑定到它时,它不会认为它已被调用。您可以尝试添加一个函数验证器(请参见中的
someAttribute
示例),以查看验证器是否正在被调用。我添加了它,但不确定在何处会看到错误,我希望在某个地方不会发生回调?奇怪的是,我无法调用model.isValid(),因为显然事件没有“validate”方法。这可能是个线索吗?