3

私は正しいアプローチが何であるか疑問に思っています。まずはテストコードです。

describe 'Something', ->
    it 'should trigger event', (done) ->
        spy = sinon.spy()
        instance = new Something()
        instance.on("itsdone", spy)
        instance.methodCall()
        spy.should.have.been.calledOnce
        done()

非常に単純に見えますが、イベントは通常非同期であるため、これは機能しません。

class Something
    constructor: ->
        @events = {}
    on: (event, cb) ->
        @events[event] = new signals.Signal() unless @events[event]?
        @events[event].add cb
    methodCall: ->
        # Fire up `itsdone` event when everything else is done
        setTimeout (=> @events['itsdone']?.dispatch()), 0

この方法では、テストは明らかに失敗します。すると、こんなことを考えていた…。

describe 'Something', ->
    it 'should be triggering even', (done) ->
        instance = new Something()
        instance.on("itsdone", done)
        instance.methodCall()

これは正しく機能し、イベントがトリガーされない場合、テストは 2 秒後に失敗します。ただし、一度だけトリガーされたという検証はありません。多分私はそのために別のテストが必要ですか?少なくとも 1 回トリガーされることは既にわかっているので、おそらくこの後にスパイでテストを使用できます。1つのイベントでは面倒すぎるようですが。

別の「汚い」アプローチは次のとおりです。

describe 'Something', ->
    it 'should be triggering even', (done) ->
        spy = sinon.spy()
        instance = new Something()
        instance.on("itsdone", spy)
        instance.methodCall()
        setTimeout ->
            spy.should.have.been.calledOnce
            done()
        , 0

それはおそらく本当に防弾ではありません。確かに、おそらくより大きなタイムアウトが必要になるでしょう。ただし、これはテストの処理に時間がかかることを意味し、これはお勧めできません。

これをどのように解決すべきか他のアイデアはありますか?

4

1 に答える 1