2012-03-08 7 views
9

Estoy escribiendo una prueba para una Vista Backbone para probar que se está llamando a la función de renderización después de obtener el modelo. La prueba es:Backbone.js ver pruebas usando Sinon Spies en un navegador

beforeEach(function() { 
    $('body').append('<div class="sidebar"></div>'); 
    profileView = new ProfileView(); 
}); 

it('should call the render function after the model has been fetched', function (done) { 
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'}); 
    var spy = sinon.spy(profileView, 'render'); 
    profileView.model.fetch({ 
     success: function() { 
      sinon.assert.called(spy); 
      done(); 
     } 
    }); 
}); 

estoy usando Spies Sinon adjuntar un objeto de espionaje a la función de procesamiento de vista el objeto profileView.

La vista es:

var ProfileView = Backbone.View.extend({ 
    el: '.sidebar' 
    , template: Hogan.compile(ProfileTemplate) 
    , model: new UserModel() 
    , initialize: function() { 
     this.model.bind('change', this.render, this); 
     this.model.fetch(); 
    } 
    , render: function() { 
     $(this.el).html(this.template.render()); 
     console.log("Profile Rendered"); 
     return this; 
    } 
}); 

Después de la zona de alcance se llama en la prueba, el evento de cambio está disparando y la función de hacer que la vista está recibiendo llamadas, pero el Sinon espía no está detectando que hacen está siendo llamado y falla.

Como un experimento, he intentado llamar a la función render en la prueba para ver si el espía lo identificó:

it('should call the render function after the model has been fetched', function (done) { 
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'}); 
    var spy = sinon.spy(profileView, 'render'); 
    profileView.render(); 
    profileView.model.fetch({ 
     success: function() { 
      sinon.assert.called(spy); 
      done(); 
     } 
    }); 
}); 

La espía detectado la llamada se hizo en el caso anterior.

¿Alguien sabe por qué el Spy no identifica la llamada de render en mi prueba inicial?

Respuesta

25

El problema es que durante la construcción de la vista, la función de inicialización vincula un evento directamente a la función de renderizado. No puede interceptar este evento con un espía porque el enlace ya ha sucedido antes de configurar su espía (lo que hace después de la construcción).

La solución es espiar el prototipo antes de construir la vista. Por lo tanto, deberá mover el espía al BeforeEach o mover la construcción de la vista a la prueba.

Para configurar el espía:

this.renderSpy = sinon.spy(ProfileView.prototype, 'render'); 
this.view = new ProfileView(); 

Luego, más tarde, para eliminar el espía:

ProfileView.prototype.render.restore() 

Esto entonces espiar 'ordinaria' llama a prestar, así como el evento de cambio de el modelo.

3

sólo 3 conjeturas:

  1. Usted está suponiendo que la devolución de llamada fetch({ success }) está siendo llamado después de la Model se ha actualizado y el evento desencadenado Modelo .. y tal vez no es así. Solución: intenta depurar el juego alrededor de here.
  2. Tal vez la llamada fetch no es éxito por lo que no se llama a la devolución de llamada exitosa. Solución: intente agregar un error de devolución de llamada al fetch para ver si es allí donde nos envían.
  3. Model.validate respuestas false, lo que es no muy probable si no lo ha implementado.

(apuesto para la 2.)

0

Esto funcionó para mí, aunque el espía se utiliza en la colección:

var thatzzz = this; 
    this.hcns.fetch({ 
     success: function(){ 
      expect(thatzzz.hcnsFetchSpy).toHaveBeenCalled(); 
     } 
}); 
  • espía se definió en beforeeach
Cuestiones relacionadas