backbone.js 为什么我做这个测试的时候没有叫上这个Sinon间谍?

abithluo  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(126)

我有一个 Backbone 模型:

class DateTimeSelector extends Backbone.Model

  initialize: ->
    @bind 'change:date', @updateDatetime
    @bind 'change:time', @updateDatetime

  updateDatetime: =>
    # do some stuff with the sate and time

我使用jasmin和sinon.js对该代码进行了一些测试

describe "DateTimeSelector", ->
  beforeEach ->
    @datetime = new DateTimeSelector()

    describe "updateDatetime", ->
      beforeEach ->
        @updateSpy = sinon.spy(@datetime, 'updateDatetime')

      afterEach ->
        @datetime.updateDatetime.restore()

      # passes
      it "should be called when we call it", ->
        @datetime.updateDatetime()
        expect(@updateSpy).toHaveBeenCalledOnce()

      # fails
      it "should be called when we trigger it", ->
        @datetime.trigger 'change:date'
        expect(@updateSpy).toHaveBeenCalled()

      # fails
      it "should be called when we set the date", ->
        @datetime.set { date: new Date() }
        expect(@updateSpy).toHaveBeenCalled()

当我在浏览器中使用它时,它似乎可以工作,但我似乎无法通过测试。有人能告诉我吗?

klr1opcd

klr1opcd1#

duckyfuzz,你遇到这个问题是因为当你创建间谍(它实际上 Package 了原始函数,并创建了一个间接层来插入跟踪方法调用的服务)事件的绑定已经发生。这意味着即使spy Package 了原始函数,事件绑定也会引用原始函数,而不是 Package 的spy。因此,当您测试时,原始函数在事件触发器上执行,但是间谍跟踪在上一级并且不执行。
为了确保事件绑定实际上指向 Package 的spy函数,你必须在创建模型对象之前创建spy(如果你在测试视图,也是这样)。要做到这一点,在类的prototype.“method”上创建spy:
beforeEach -〉部分中,在@日期时间=新日期时间选择器()之前创建间谍:@更新时间监视= sinon.spy(* 日期时间选择器.原型 ,'更新日期时间')*
一定要修改
afterEach -〉部分,在这里您可以将原型恢复为正常状态,如下所示:@更新间谍还原()**
您代码应该是:

describe "DateTimeSelector", ->
  beforeEach ->
    @updateSpy = sinon.spy(DateTimeSelector.prototype, 'updateDatetime')
    @datetime = new DateTimeSelector()

  afterEach ->
    @updateSpy.restore()

  # passes
  it "should be called when we call it", ->
    @datetime.updateDatetime()
    expect(@updateSpy).toHaveBeenCalledOnce()

  # should pass now
  it "should be called when we trigger it", ->
    @datetime.trigger 'change:date'
    expect(@updateSpy).toHaveBeenCalled()

  # should pass now
  it "should be called when we set the date", ->
    @datetime.set { date: new Date() }
    expect(@updateSpy).toHaveBeenCalled()

顺便说一句,如果您使用的是jasmin-sinon.js插件,那么您的语法是好的

zysjyyx4

zysjyyx42#

你把茉莉花和西农的讽刺语法混在一起了。
在通过测试中,sinon spy暴露了calledOnce属性,但是使用了jasmine风格的函数toHaveBeenCalledOnce(),这个函数在sinon spy上并不存在,所以实际上没有发生assert。
在你失败的测试中,你调用了sinon spy上的jasmine spy函数toHaveBeenCalled()spyOn(obj, 'method');

相关问题