2012-02-29 14 views
5

Non so come eseguire questo test Jasmine per il mio JS e sicuramente anche altri ppl hanno questo problema. Forse sto sbagliando o forse è impossibile - non ho trovato alcun indizio su questo. Il problema ha a che fare con il fatto che - in jQuery - $ (questo) non è uguale all'elemento scelto da es. $ ("# Questo-id"):

Javascript:

[..] 
$("#button-id").on("click", function(e) { callSomeFunctionWith($(this)); }); 

Jasmine-Test (CoffeeScript):

[..] 
spyOn some.object, "callSomeFunctionWith" 
spyOnEvent($("#button-id"), 'click') 

$("#button-id").trigger("click") 
expect(some.object.callSomeFunctionWith).toHaveBeenCalledWith($("#button-id")) 

Purtroppo questo test fallisce (con ogni variazione come la memorizzazione l'arbitro per in una variabile prima nel mio test Jasmine), perché la funzione NON è chiamata con $ ("# button-id"), ma viene invece chiamata con $ (this), e $ (this)! = $ ("# button- id ").

Qualcuno può dirmi come eseguire questo test? Sono abbastanza perso. Anche lo Remy Sharp's great article on jQuery and $(this) non mi ha più aiutato.

risposta

4

Ok, ora ho la soluzione al mio problema. La soluzione è semplice, la spiegazione no. Spiegherò la soluzione da zero.

Questo è il mio codice Javascript con jQuery che voglio testare usando il gelsomino-jQuery:

$("input.toggler").on("click", function(e) { 
    [...] 
    doSomethingWith($(this)); 
}); 

E ora utilizzando Jasmine-jQuery voglio garantire che la funzione JS "doSomethingWith" viene chiamato con il corretto "$ (this)".

Prima si potrebbe pensare che $ (this) === $ ("input.toggler"), ma questo non è vero. All'interno della funzione di callback del gestore di clic, $ (this) jQuery utilizza non è né l'oggetto jQuery $ ("input.toggler") né l'elemento DOM a cui fa riferimento tale oggetto. Come spiega Remy Sharp nel suo bellissimo articolo "jQuery's this: demystified", il "questo" all'interno della funzione di callback è l'elemento DOM, ma $ (this) crea un oggetto jQuery da quell'elemento DOM. E questo non è identico all'oggetto jQuery $ ("input.toggler").

Quindi, se vuoi testarlo con Jasmine usando la funzione "toHaveBeenCalledWith", devi prima estrarre l'elemento DOM usando document.getElementById (...) oppure document.getElementsByTagName (...) [INDICE ] (dove INDICE è l'indice dell'elemento che si desidera, poiché quest'ultima funzione fornisce una matrice di elementi DOM), che è semplice vecchio Javascript. Quindi, quando hai estratto l'elemento DOM desiderato, devi creare un oggetto jQuery da esso racchiudendolo in $ (e).

mio passaggio Jasmine-jQuery-test appare finalmente qualcosa di simile (usando CoffeeScript):

it "does something with my input element", -> 
    DOM_input_element = document.getElementsByTagName("input")[0] # Choose the correct DOM element here 

    spyOn myobject.functions, "doSomethingWith" 
    spyOnEvent($('input.toggler'), 'click') 

    [...] 

    $('input.toggler').trigger('click') 

    # Check for changes after click: 
    expect(myobject.functions.doSomethingWith).toHaveBeenCalledWith($(DOM_input_element)) 

modo che il "$ (this)" dal mio codice JavaScript si traduce in "$ (DOM_input_element)" nella mia Test Jasmine-jQuery.

Speriamo che questo ti aiuti con i tuoi progetti! Mi ci è voluto un po 'per capirlo.