为什么我运行这个测试时没有调用这个 sinon spy? [英] Why is this sinon spy not being called when I run this test?

查看:12
本文介绍了为什么我运行这个测试时没有调用这个 sinon spy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个骨干模型:

class DateTimeSelector extends Backbone.Model

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

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

我使用 jasminsinon.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()

当我在浏览器中使用它时,它似乎可以工作,但我似乎无法通过测试.谁能给我指点一下?

It seems to work when I use it in the browser but I can't seem to get the tests to pass. Can anyone enlighten me?

推荐答案

duckyfuzz,您遇到这个问题是因为当您创建 spy(它实际上包装了原始函数并创建了一个间接级别以插入其跟踪服务方法调用)事件的绑定已经发生.这意味着即使间谍包装了原始函数,事件绑定也引用了原始函数而不是包装的间谍.因此,当您进行测试时,原始函数在事件触发器上执行,但间谍跟踪在上一级并没有执行.

duckyfuzz, you are experiencing this problem because when you are creating the spy (which actually wraps the original function and creates a level of indirection to insert its services of tracking method invocation) the binding of the events has already taken place. Which means that even though the spy wrapped the original function the event binding references the original function and not the wrapped spy. Hence, when you test, the original function gets executed on the event trigger but the spy tracking is one level above and is not executed.

要确保事件绑定实际上指向封装的 spy 函数,您必须在创建模型对象之前创建 spy(如果您正在测试视图,则同样如此).为此,在类的原型上创建间谍.方法":

To make sure that the event binding is actually pointing to the wrapped spy function you have to create the spy before create the model object (same goes if you are testing views). To do that create the spy on the prototype."method" of the class:

@datetime = new DateTimeSelector() 之前的 beforeEach -> 部分中创建间谍:@updateSpy = sinon.spy(DateTimeSelector.原型, 'updateDatetime')

in the beforeEach -> section before @datetime = new DateTimeSelector() create the spy: @updateSpy = sinon.spy(DateTimeSelector.prototype, 'updateDatetime')

一定要改变你的 afterEach -> 部分,在那里你将原型恢复正常,就像这样:@updateSpy.restore()

be sure to change your afterEach -> section where you return the prototype back to normal, like so: @updateSpy.restore()

这应该是您的代码:

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 插件,那么您的语法是没问题的

BTW, if you are using jasmin-sinon.js plugin then your syntax is fine

这篇关于为什么我运行这个测试时没有调用这个 sinon spy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆