20

tengo un modelo Backbone:¿Por qué no se llama a este espía sinon cuando ejecuto esta prueba?

class DateTimeSelector extends Backbone.Model 

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

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

y tengo algunas pruebas de que el código usando jasmin y 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() 

Parece que funciona cuando lo uso en el navegador, pero no puedo parecen hacer que las pruebas pasen. ¿Alguien puede iluminarme?

+1

Es posible que desee volver a etiquetar para incluir 'coffeescript'. Te lo habría agregado pero estás al máximo a las 5 y no quería decidir cuál reemplazar por ti. – Kai

+0

Sí, nunca sé qué hacer en esta situación. La pregunta está escrita en Coffee obviamente, pero el problema y la solución no están (probablemente) relacionados con coffeescript. Así que no sé si es correcto etiquetar como coffeescript. –

+1

Bueno, miré esta pregunta porque estaba etiquetada JS; pero no puedo ayudar porque el ejemplo es coffeescript que no utilizo yo mismo. Así que pensé que una etiqueta de coffeescript podría atraer a otros usuarios de coffeescript, que podrían leer y comprender más fácilmente tu ejemplo. :) – Kai

Respuesta

47

duckyfuzz, está experimentando este problema porque cuando está creando el espía (que en realidad ajusta la función original y crea un nivel de indirección para insertar sus servicios de método de seguimiento de invocación) la unión de los eventos ya ha tenido lugar. Lo que significa que aunque el espía envolvió la función original, el enlace del evento hace referencia a la función original y no al espía envuelto. Por lo tanto, cuando prueba, la función original se ejecuta en el desencadenador de eventos, pero el seguimiento de espías está en un nivel superior y no se ejecuta.

Para asegurarse de que el enlace de evento apunta realmente a la función de espionaje envuelto, debe crear el espía antes de crear el objeto modelo (lo mismo ocurre si está probando vistas). Para hacer esto, cree que el espía en el prototipo "método" de la clase:.

en el beforeeach -> sección antes @datetime = new DateTimeSelector() crear el espía: @updateSpy = sinon.spy (DateTimeSelector.prototype, 'updateDatetime')

asegúrese de cambiar su afterEach - sección> donde se devuelva el prototipo de volver a la normalidad, así: @ updateSpy.restore()

este debe ser su código:

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() 

Por cierto, si usted está usando el plugin de jasmin-sinon.js entonces su sintaxis es bien

+0

Ese fue exactamente mi problema. Gracias. – EndangeredMassa

+0

Se metió en el mismo problema exacto, gracias por la muestra de código correcto! – berg

+3

votaría dos veces si pudiera :) –

0

Estás mezclando la sintaxis burlona de jazmín y sinón.

En su paso probar su espía sinon expone la propiedad calledOnce pero que está utilizando una función de jazmín al estilo toHaveBeenCalledOnce(). Esta función no existe en el espía de sinón, por lo que esencialmente no está teniendo lugar ninguna afirmación.

En sus pruebas fallidas llama a la función espía de jazmín toHaveBeenCalled() en su espía sinon. Jasmine tiene su propia sintaxis para crear un espía: spyOn(obj, 'method');

Cuestiones relacionadas