2012-02-29 19 views
5

No sé cómo ejecutar esta prueba de Jasmine para mi JS y seguramente también otras personas tienen este problema. Tal vez estoy equivocado o tal vez sea imposible, no encontré ninguna pista sobre esto. El problema tiene que ver con el hecho de que, en jQuery, $ (esto) no es lo mismo que el elemento elegido, p. $ ("# Esto-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")) 

Desafortunadamente no pasa esta prueba (con cualquier variación, como el almacenamiento que el árbitro en una variable primero en mi prueba de Jasmine), porque la función NO se llama con $ ("# button-id"), sino que se llama con $ (this), y $ (this)! = $ ("# button- carné de identidad").

¿Alguien me puede decir cómo lograr esta prueba? Estoy perdido. Incluso Remy Sharp's great article on jQuery and $(this) no me ayudó más.

Respuesta

4

Bien, ahora tengo la solución a mi problema. La solución es fácil, la explicación no. Explicaré la solución desde cero.

Este es mi código Javascript con jQuery que quiero poner a prueba el uso de jazmín-jquery:

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

Y ahora el uso de jazmín-jQuery Quiero asegurar que la función JS "doSomethingWith" se llama a la correcta "$ (esto)".

Primero, uno puede pensar que $ (this) === $ ("input.toggler"), pero eso no es cierto. Dentro de la función de devolución de llamada del manejador de clics, el $ (este) jQuery no es ni el objeto jQuery $ ("input.toggler") ni el elemento DOM al que hace referencia ese objeto. Como explica Remy Sharp en su artículo realmente bueno "jQuery's this: demystified", el "this" dentro de la función de devolución de llamada es el elemento DOM, pero $ (esto) crea un objeto jQuery a partir de ese elemento DOM. Y eso no es idéntico al jQuery object $ ("input.toggler").

Así que si quieres probar esto con Jasmine usando la función "toHaveBeenCalledWith", primero tienes que extraer el elemento DOM utilizando ya sea document.getElementById (...) o bien document.getElementsByTagName (...) [ÍNDICE ] (donde INDEX es el índice del elemento que desea, ya que la última función le proporciona una matriz de elementos DOM), que es el antiguo Javascript simple. Luego, cuando haya extraído el elemento DOM deseado, debe crear un objeto jQuery a partir del mismo adjuntándolo en $ (y).

Mi Jasmine-jQuery-test que pasa finalmente se ve algo como esto (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)) 

lo que el "$ (this)" de mi código Javascript se traduce en "$ (DOM_input_element)" en mi Prueba Jasmine-jQuery.

¡Espero que esto lo ayude con sus proyectos! Me tomó bastante tiempo resolver esto.

Cuestiones relacionadas