1

CoffeeScriptalaSpinejsで単純なMVCパターンを使用しています。インスタンス化の前にイベントオブジェクトを指定することで、イベントリスナーを追加できます。

class Controller extends Module
    @include Events

    eventSplitter: /^(\S+)\s*(.*)$/
    events: {}

    constructor: (view = '<div/>') ->
        @view = $(view)
        @delegate key, func for key, func of @events

    delegate: (key, func) ->
        match = key.match @eventSplitter
        if match[2] is ''
            @view.on( match[1], $.proxy(@[func], @) )
        else
            @view.on( match[1], match[2], $.proxy(@[func], @) )

簡単な説明-viewプロパティに割り当てられるセレクター、要素、またはhtml文字列を渡します。次に、delegateメソッドはイベントのオブジェクトを取得してループし、イベントリスナーをビューノード自体に割り当てるか、イベントハンドラーを子要素からビューノードに委任します。

class Con extends Controller
    events:
        'click' : 'parent'
        'mouseover span' : 'child'

    parent: (e) ->
        console.log('div was clicked')

    child: (e) ->
        console.log('span was moused over')

con = new Con('<div><span>test</span></div>')

con.view.trigger('click') // --> 'div was clicked'
con.view.find('span') // --> 'span was moused over'

私はこれをジャスミンでテストするのに苦労しています。次のテストに合格します。

expect( con.view ).toHandle('mouseover')
expect( con.view ).toHandle('click')

これにより、少なくともある種のハンドラーが設定されていることをテストできますが、実際に設定されているハンドラーをテストしたいと思います。イベントハンドラーをスパイしようとしていますが、呼び出されていないようです。

spyOn(con, 'parent')
con.view.trigger('click')

expect( con.parent ).toHaveBeenCalled() // fails!

また、プロトタイプの実際の方法をスパイしようとしました。

spyOn( Con.prototype, 'parent' )
con.view.trigger('click')

expect( Con.prototype.parent ).toHaveBeenCalled() // fails!

メソッドを明示的に呼び出すと、テストに合格することができます。

con.parent();
expect( con.parent ).toHaveBeenCalled() // passes!

イベントハンドラーがjQuery'on'メソッドを介して参照される方法が原因で、イベントによって実行されたときにスパイが失敗すると思います。関数のようですが、conオブジェクトにある実際のメソッドではありません。

どんな助けでもいただければ幸いです。一般的なテストのアドバイスも歓迎します。

4

2 に答える 2

1

解決策は、オブジェクトの外部でスパイを定義することのようです。ベアスパイを作成するjasmine.createSpy()メソッドを発見しました。まさに、必要なものです。

describe "Controller", ->
    clickSpy = jasmine.createSpy()
    mouseSpy = jasmine.createSpy()

    class Con extends CRDGN.Controller
        events:
            'click' : 'parent'
            'mouseover span' : 'child'

        parent: clickSpy

        child: mouseSpy

    con = new Con('<div><span>test</span></div>')

it "should attach listeners through an events object", ->
    con.view.trigger('click')
    expect( clickSpy ).toHaveBeenCalled()

    con.view.find('span').trigger('mouseover')
    expect( mouseSpy ).toHaveBeenCalled()
于 2012-08-10T16:08:53.770 に答える
1

Jasmineには、実際には、テスト対象システムをオーバーライドせずにこれを実行できるspyOnメソッドがあります。

この特定のコードを実行していないことは認めますがspyOn、2つのテストを使用して分割する回答のリファクタリングを次に示します。

describe 'CRDGN.Controller', ->
  it 'should attach a click listener', =>
    clickSpy = spyOn(CRDGN.Controller, 'parent')
    controller = @_buildController()

    controller.view.trigger('click')

    expect(clickSpy).toHaveBeenCalled()

  it 'should attack a mouseover listener for <span>', =>
    mouseSpy = spyOn(CRDGN.Controller, 'child')
    controller = @_buildController()

    controller.view.find('span').trigger('mouseover')

    expect(mouseSpy).toHaveBeenCalled()

  _buildController: () ->
    new CRDGN.Controller('<div><span>test</span></div>')
于 2013-08-29T18:00:54.587 に答える