2

バックボーンモデルを検証するためにbackbone.validationを使用しており、作業にTDDアプローチを採用しています。残念ながら、フィールドが実際に必要であるかどうかをテストするときに、スパイを呼び出させることができないようです。

私はジャスミンとシノンでバックボーンアプリケーションをテストするチュートリアルに従ってきましたが 、彼がスパイを登録するときを除いて、"error"私は私のものをに登録しようとしました"invalid"。これは、readmeの「イベント」セクションで説明されているように、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オブジェクトをさらに調べると、スパイが呼び出されていないことがわかります。

これは、backbone.validation readmeで定義されているように、モデルのプロトタイプの検証を混合することと関係があると思いますが、 _.extend(Backbone.Model.prototype, Backbone.Validation.mixin);これも機能しないようです。

私はこのテストを実行したときになぜこのシノンスパイが呼び出されないのかという質問を見てきました。しかし、答えを自分のコードに組み込むこともできませんでした。

誰かが私が間違っていることを教えてくれたら、私はとても感謝しています!

修正済み コードを次のように修正しました。(1)_.extend Backbone.Model::, Backbone.Validation.mixinアプリケーションに追加しました

(2)次に、この質問で与えられたアドバイスに従って、初期化時にスパイをバインドしました。コードは次のようになります。モデル:クラス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 を追加するコードが含まれていることを確認しましたか?

特定のビューではなく、アプリケーション全体でモデルの検証済みイベントにバインドできるようにする場合は、次のように記述して mixin を追加する必要があります。

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

これは、coffeescript を使用してアプリケーションに次のように記述できます。

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

このコードをメインの Backbone アプリ ファイルに追加します。

これを行ったら、スパイの問題がこの質問にリンクされている可能性があります-イベントハンドラーをバインドする前に、適切なタイミングでスパイをバインドしていることを確認する必要があります。前のリンクのソリューションは、initialize にフックすることでこれを行います。

于 2012-11-05T19:59:39.237 に答える
0

間違ったイベントにバインドしているだけだと思います。細かいマニュアルから:

検証済み

イベントは、validated検証が成功したかどうかに関係なく、検証が実行された後にトリガーされます。または検証の結果isValidに応じて。truefalse

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 に答える