单元测试骨干模型保存句柄

时间:2017-01-09 07:12:07

标签: unit-testing backbone.js coffeescript sinon chai

我有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

1 个答案:

答案 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