2012-03-08 14 views
9

Sto scrivendo un test per una vista Backbone per verificare che la funzione di rendering venga chiamata dopo aver recuperato il modello. Il test è:Backbone.js visualizza i test utilizzando Sinon Spies in un browser

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

sto usando Spies Sinon per collegare un oggetto spia per la funzione di rendering dell'oggetto vista profiloVedi.

La vista è:

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; 
    } 
}); 

Dopo l'operazione di recupero è chiamato nel test, l'evento di modifica sta sparando e la funzione del render di vista è sempre chiamato, ma la Sinon spia non rileva che la rendono sia essendo chiamato e fallisce.

Come esperimento, ho provato a chiamare la funzione rendering nel test per vedere se la spia identificato:

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 spia rilevato la chiamata è stata fatta nel caso precedente.

Qualcuno sa perché la spia non sta identificando la chiamata di rendering nel mio test iniziale?

risposta

25

Il problema è che durante la costruzione della vista, la funzione di inizializzazione lega un evento direttamente alla funzione di rendering. Non puoi intercettare questo evento con una spia perché la legatura è già avvenuta prima di configurare la tua spia (che fai dopo la costruzione).

La soluzione è di spiare il prototipo prima di costruire la vista. Quindi dovrai spostare la spia in BeforeEach o spostare la costruzione della vista nel test.

Per impostare la spia:

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

Poi, più tardi, per rimuovere la spia:

ProfileView.prototype.render.restore() 

Questo sarà quindi spiare 'ordinaria' chiamate a rendere, così come l'evento di modifica da il modello.

3

soli 3 ipotesi:

  1. Stai pensando che i fetch({ success }) callback viene chiamato dopo che la Model è stato aggiornato e l'evento innescato modello .. e forse non è così. Soluzione: provare a eseguire il debug attorno a here.
  2. Forse la chiamata fetch non è successo quindi non viene richiamata la chiamata di successo. Soluzione: prova ad aggiungere un callback all'errore allo fetch per vedere se è lì dove siamo inviati.
  3. Le risposte Model.validatefalse, cosa è non molto probabile se non è stato implementato.

(scommetto per il 2.)

0

Questo ha funzionato per me, anche se la spia è utilizzato nella collezione:

var thatzzz = this; 
    this.hcns.fetch({ 
     success: function(){ 
      expect(thatzzz.hcnsFetchSpy).toHaveBeenCalled(); 
     } 
}); 
  • spia è stato definito sulla beforeeach
Problemi correlati