我想知道什么是正确的方法。首先是测试代码。
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 秒后失败。但是没有验证,它只被触发了一次。也许我需要另一个测试?因为我已经知道它至少被触发了一次,所以我可以在这个之后使用 test 和 spy 。虽然对于一个事件来说似乎太麻烦了。
另一种“肮脏”的方法可能是:
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
它可能不是真正的防弹。可能需要更大的超时时间才能确定。然而,这意味着测试将需要更长的时间来处理,这不是一个好主意。
您还有其他想法应该如何解决?