我有submit
方法的视图。如何编写单元测试以检查是否在以下代码中触发了事件
submit:(event) ->
MyModel.save(null, {
success: (model, response)=>
@trigger('saveSuccess', response)
})
注意:我不想检查成功是否被称为
尝试:
it 'Should trigger events on save', (done) ->
originalSave = MyModel.save
triggerSpy = sinon.spy()
MyModel.on('rating:saveSuccess', triggerSpy)
stub = sinon.stub(MyModel, "save", ->
successSpy = sinon.spy(arguments[1].success)
originalSave.apply(MyModel, arguments);
# want to call this line in the successSpy callback
expect(triggerSpy.callCount).to.equal(1);
done()
)
MyView.submit({})
expect(stub).to.have.been.called
修改 第二次尝试(工作但不确定其正确的方法)
it 'Should trigger events on save', (done) ->
triggerSpy = sinon.spy()
MyView.on('saveSuccess', triggerSpy)
stub = sinon.stub(MyModel, "save", ->
arguments[1].success()
expect(triggerSpy.callCount).to.equal(1);
done()
)
MyView.submitReval({})
expect(stub).to.have.been.called
答案 0 :(得分:2)
进行单元测试时,需要对相关单元做出决定。测试开始和结束的时间/地点。您可以决定使用Istanbul等工具计算的代码覆盖率非常重要。
您的第一个示例将运行Model.save
代码,立即断言事件已被触发。这意味着您将100%覆盖此功能。但请记住,Model.save
已运行,您可能不希望覆盖模型。很可能这不起作用,因为save
操作不是同步的,因此断言在代码完成之前运行。如果您还没有使用过sinon的fakeServer,那么您应该考虑它。
您的第二个示例存根Model.save
并且从不运行它。这将为您提供1行代码覆盖率(50%),但考虑到此处理程序只有一行,您需要询问此测试是否具有此方式的任何值。
如果您是单位测试纯粹主义者,并希望此单元测试仅为测试中的功能添加覆盖范围,则以下方法可行:
it 'Should trigger events on save', ->
triggerSpy = sinon.spy()
MyModel.on('saveSuccess', triggerSpy)
stub = sinon.stub(MyModel, "save", (attr, opts) ->
opts.success.apply(null, [this, {}])
)
MyView.submit({})
expect(stub).to.have.been.called
expect(triggerSpy.callCount).to.equal(1)
expect(triggerSpy.args[0][0]).to.deep.equal({})
这提供了100%的功能覆盖(仍然只有2行,但这是功能)。现在它是同步的,Model.save
没有被调用,而是被存根。它断言函数的最终输出,触发事件。它还测试保存的响应是否包含在事件中。
如果你不是纯粹主义者,那就看看sinon的fakeServer。