2011-09-28 4 views
8

Sto cercando di implementare vista dei test per un'implementazione CoffeeScript dei backbone.js onnipresenti 'todo' esempio (vedi github.com/rsim/backbone_coffeescript_demo.)backbone.js test visualizzare gli eventi con il gelsomino

mio gelsomino i test della demo sopra funzionano abbastanza bene, ad eccezione degli eventi di visualizzazione. Mi aspetto che io sia bloccato su uno o entrambi i seguenti punti i) Non capisco il binding dell'evento nel codice della vista, ii) Non capisco come configurare correttamente il test Jasmine degli eventi del codice di visualizzazione.

Ecco un esempio della manifestazione 'modifica' ...

class TodoApp.TodoView extends Backbone.View 
    tagName: "li" 
    template: TodoApp.template '#item-template' 
    events: 
    "dblclick div.todo-content" : "edit" 
    ... 

    initialize: -> 
    _.bindAll this, 'render', 'close' 
    @model.bind 'change', @render 
    @model.bind 'destroy', => @remove() 

    render: -> 
    $(@el).html @template @model.toJSON() 
    @setContent() 
    this 

    edit: -> 
    $(@el).addClass "editing" 
    @input.focus() 
    ... 

... ora ecco una prova di se messa a fuoco è stato ottenuto su un doppio clic:

describe "edit state", -> 
     li = null 

    beforeEach -> 
     setFixtures('<ul id="todo-list"></ul>') 
     model = new Backbone.Model id: 1, content: todoValue, done: false 
     view = new TodoApp.TodoView model: model, template: readFixtures("_item_template.html") 
     $("ul#todo-list").append(view.render().el) 
      li = $('ul#todo-list li:first') 
     target = li.find('div.todo-content') 
     expect(target).toExist() 
       target.trigger('dblclick') # here's the event! 

    it "input takes focus", -> 
     expect(li.find('.todo-input').is(':focus')).toBe(true) 

L'aspettativa su né io) la spia né ii) l'attenzione è soddisfatta.

Esiste una particolarità nel test del codice dell'evento backbone.js su cui dovrei essere a conoscenza in Jasmine?

+0

Sto incontrando lo stesso problema. Hai trovato una soluzione per questo? –

+0

@Michal - no non l'ho fatto. – Lille

+0

Anche avendo un problema simile, ancora nessuna idea? –

risposta

2

stai spiando il metodo edit della vista. questo sostituisce il metodo con un oggetto spia, il che significa che il metodo di modifica effettivo non verrà richiamato. quindi, sei @input.focus non sparerà mai.

dato che si desidera che il test invochi effettivamente il metodo di modifica, rimuoverei la spia.

nota a margine: non chiamare i metodi expect in precedenza. se hai davvero bisogno di impostare un'aspettativa su quelli, crea un blocco it per loro.

+0

Grazie, ho rimosso qualsiasi spionaggio di Jasmine e ancora non riesco a ottenere il focus atteso. – Lille

+0

Penso che le tue spie e i tronconi confusionari. Spys avvolge il metodo ma consente il passaggio della chiamata. – user1464581

2

Non sono bravo con il manoscritto quindi potrei mancarmi qualcosa ma dove stai impostando la tua spia?

Per verificare le chiamate di eventi potrebbe essere necessario aggiornare gli eventi della vista dopo aver configurato la spia.

spyOn(view, 'edit'); 
view.delegateEvents(); 
target.trigger('dblclick'); 

it("should call edit when target is double clicked", function() { 
    expect(view.edit).toHaveBeenCalled() 
}); 
0

Non ho scritto la mia prova in CoffeeScript, ma ho avuto lo stesso problema, quindi spero che mi perdonerete per rispondere a javadcript. Ho finito per suddividere il test in due test diversi. Innanzitutto, ho provato se chiamare la funzione di modifica della vista impostava lo stato attivo sulla casella di input. Successivamente, ho verificato se la modifica è stata chiamata quando l'etichetta è stata cliccata due volte e non ha ancora ottenuto il test per passare. Ma ecco come ho provato se la funzione di modifica ha funzionato.

Qualcosa che potrebbe causare problemi è che il tuo modello E la tua vista sono dichiarati prima di Ogni altro. Dichiarandoli all'interno prima di Each significa che esistono solo all'interno dell'ambito di Eaches e non esistono più quando lo si esegue.

Inoltre, setFixtures fa quello che pensi che faccia? La messa a fuoco non può essere impostata su un elemento che non fa parte dell'albero DOM, quindi ho aggiunto l'el della vista al corpo della specifica jasmine stessa. (Sto usando lo specrunner html, non la versione da linea di comando) che lo rende parte del dom tree e quindi permette di avere lo stato attivo, e rende anche se ha messa a fuoco testabile.

0

Il problema con questo è che l'oggetto Backbone.View events utilizza event delegation. Affinché gli eventi possano essere chiamati work l'elemento deve essere parte del DOM, puoi farlo facendo qualcosa come $('body').append(someView.el) nel tuo beforeEach.Personalmente, cerco di non verificare se Backbone sta impostando correttamente lo events e innescando manualmente i clic, è più pratico che i test unitari richiamino i gestori di callback evitando completamente il DOM che può rallentare molto i test.

Per :focus è lo stesso problema, ci deve essere un elemento nel DOM in modo che jQuery possa dire se un elemento è focalizzato. In questo caso è meglio impostare lo stato come parte del componente e non controllare lo stato tramite l'interrogazione del DOM, ad esempio someView.hasFocus === true. In alternativa puoi spiare l'implementazione degli elementi focus e controllare se è stata chiamata.