22

私はバックボーンモデルを持っています:

class DateTimeSelector extends Backbone.Model

  initialize: ->
    @bind 'change:date', @updateDatetime
    @bind 'change:time', @updateDatetime

  updateDatetime: =>
    # do some stuff with the sate and time

そして、 jasminsinon.jsを使用してそのコードのテストをいくつか行っています

describe "DateTimeSelector", ->
  beforeEach ->
    @datetime = new DateTimeSelector()

    describe "updateDatetime", ->
      beforeEach ->
        @updateSpy = sinon.spy(@datetime, 'updateDatetime')

      afterEach ->
        @datetime.updateDatetime.restore()

      # passes
      it "should be called when we call it", ->
        @datetime.updateDatetime()
        expect(@updateSpy).toHaveBeenCalledOnce()

      # fails
      it "should be called when we trigger it", ->
        @datetime.trigger 'change:date'
        expect(@updateSpy).toHaveBeenCalled()

      # fails
      it "should be called when we set the date", ->
        @datetime.set { date: new Date() }
        expect(@updateSpy).toHaveBeenCalled()

ブラウザで使用すると動作するようですが、テストに合格できないようです。誰かが私を啓発できますか?

4

2 に答える 2

53

duckyfuzz、この問題が発生しているのは、スパイを作成しているときに(実際には元の関数をラップし、追跡メソッド呼び出しのサービスを挿入するための間接参照のレベルを作成している)、イベントのバインドがすでに行われているためです。つまり、スパイが元の関数をラップしたとしても、イベントバインディングは、ラップされたスパイではなく、元の関数を参照します。したがって、テストすると、元の関数はイベントトリガーで実行されますが、スパイトラッキングは1レベル上にあり、実行されません。

イベントバインディングが実際にラップされたスパイ関数を指していることを確認するには、モデルオブジェクトを作成する前にスパイを作成する必要があります(ビューをテストしている場合も同様です)。これを行うには、クラスのprototype."method"にスパイを作成します。

beforeEach->セクションの前@datetime=new DateTimeSelector()でスパイを作成します:@updateSpy = sinon.spy(DateTimeSelector.prototype、'updateDatetime')

@ updateSpy.restore()のように、プロトタイプを通常に戻すafterEach->セクションを必ず変更してください。

これはあなたのコードでなければなりません:

describe "DateTimeSelector", ->
  beforeEach ->
    @updateSpy = sinon.spy(DateTimeSelector.prototype, 'updateDatetime')
    @datetime = new DateTimeSelector()

  afterEach ->
    @updateSpy.restore()

  # passes
  it "should be called when we call it", ->
    @datetime.updateDatetime()
    expect(@updateSpy).toHaveBeenCalledOnce()

  # should pass now
  it "should be called when we trigger it", ->
    @datetime.trigger 'change:date'
    expect(@updateSpy).toHaveBeenCalled()

  # should pass now
  it "should be called when we set the date", ->
    @datetime.set { date: new Date() }
    expect(@updateSpy).toHaveBeenCalled() 

ところで、jasmin-sinon.jsプラグインを使用している場合は、構文に問題はありません。

于 2012-01-26T01:10:02.583 に答える
0

ジャスミンとシノンのモック構文を混ぜ合わせています。

合格テストでは、シノンスパイがプロパティを公開しますcalledOnceが、ジャスミン風の関数を使用していますtoHaveBeenCalledOnce()。この関数はsinonスパイには存在しないため、基本的にアサートは行われません。

失敗したテストでは、シノンスパイのジャスミンスパイ関数toHaveBeenCalled()を呼び出しています。Jasmineには、スパイを作成するための独自の構文があります。spyOn(obj, 'method');

于 2011-12-15T20:37:16.067 に答える