ruby-on-rails - 使用backbone.validation测试 Backbone 模型验证 - spy 永远不会被调用

标签 ruby-on-rails validation backbone.js coffeescript jasmine

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

我一直在关注Testing Backbone applications with Jasmine and Sinon上的教程 除非他用“错误”注册他的 spy ,我已经尝试用“无效”注册我的 spy 。这样做的原因是因为我认为backbone.validation 使用无效/有效回调,而不是如自述文件的事件部分中所述。

我的问题是我收到错误消息说我的 spy 从未被召唤过。我尝试将绑定(bind)更改回错误/保存,但仍然没有运气。

我的代码如下:

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 永远不会调用。

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

我已经查看了问题 Why is this sinon spy not being called when I run this test?但是我也没能将答案合并到我的代码中。

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

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

(2) 然后我遵循 this question 中给出的建议在初始化时绑定(bind)我的 spy 。代码现在如下所示: 该模型: 事件类扩展了 Backbone.Model 网址:-> '/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();

最佳答案

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

如果您希望能够在整个应用程序中绑定(bind)到模型中经过验证的事件而不是特定 View ,那么您需要通过编写来添加混合

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

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

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

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

完成此操作后,您的 spy 问题可能会链接到 this question - 在绑定(bind)任何事件处理程序之前,您需要检查是否在正确的时间绑定(bind)了 spy 。上一个链接中的解决方案通过 Hook 初始化来实现此目的。

关于ruby-on-rails - 使用backbone.validation测试 Backbone 模型验证 - spy 永远不会被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13207366/

相关文章:

ruby-on-rails - Rails redirect_to - 我也想重新加载页面

ruby-on-rails - Rails 3.1、Ruby 1.9.2-p180 和 UTF-8 问题

javascript - 使用 Javascript 限制文本区域的字符和行

ruby-on-rails - 如何设置本地 SSL 证书和 Rails 应用程序?

php - 提交发生后如何在文本输入中保留值?

ruby-on-rails - 简单的 Rails 格式验证未触发

Backbone.js 路由器初始化不会立即运行

javascript - backbone.js 从 JSON 渲染多级 ul-list

Javascript、jquery、backbone、splunk : on ("change", {data}、处理程序)导致 TypeError

ruby-on-rails - Rails GeoCoder,循环遍历现有数据库和 geocode_by :address, :city, :state