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オブジェクトにある実際のメソッドではありません。
どんな助けでもいただければ幸いです。一般的なテストのアドバイスも歓迎します。