Как протестировать jQuery с Jasmine для $ ("# element-id"), если используется как $ (this) - PullRequest
5 голосов
/ 29 февраля 2012

Я не знаю, как запустить этот тест Жасмин для моего JS, и, конечно же, другие люди имеют эту проблему. Может быть, я делаю что-то неправильно или, возможно, это невозможно - я не нашел намека на это. Проблема связана с тем, что - в jQuery - $ (this) не совпадает с элементом, выбранным, например, $ ( "# Это-идентификатор"):

Javascript:

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

Жасмин-тест (CoffeeScript):

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

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

К сожалению, этот тест не пройден (с любым изменением, таким как сохранение ссылки на переменную сначала в моем тесте Жасмин), потому что функция НЕ вызывается с $ ("# button-id"), а вместо этого вызывается с $ ( this) и $ (this)! = $ ("# button-id").

Кто-нибудь может сказать мне, как выполнить этот тест? Я совсем потерян. Даже замечательная статья Реми Шарпа о jQuery и $ (this) не получила меня дальше.

1 Ответ

4 голосов
/ 01 марта 2012

Хорошо, теперь у меня есть решение моей проблемы.Решение простое, объяснения нет.Я объясню решение с нуля.

Это мой код Javascript с jQuery, который я хочу протестировать с помощью jasmine-jquery:

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

А теперь, используя Jasmine-jQuery, я хочуубедитесь, что функция JS "doSomethingWith" вызывается с правильным значением "$ (this)".

Сначала можно подумать, что $ (this) === $ ("input.toggler"), но этоне правда.Внутри функции обратного вызова обработчика щелчков используемый jQuery $ (this) не является ни объектом jQuery $ ("input.toggler"), ни элементом DOM, на который ссылается этот объект.Как объясняет Реми Шарп в своей действительно хорошей статье « jQuery's this: demystified », «this» внутри функции обратного вызова является элементом DOM, но $ (this) создает объект jQuery из этого элемента DOM.И это не идентично объекту jQuery $ ("input.toggler").

Так что если вы хотите проверить это с помощью Jasmine, используя функцию "toHaveBeenCalledWith", вы должны сначала извлечь элемент DOM, используя либоdocument.getElementById (...) или же document.getElementsByTagName (...) [INDEX] (где INDEX - это индекс элемента, который вы хотите, поскольку последняя функция выдает массив элементов DOM), который является довольно старымJavascript.Затем, когда вы извлекли требуемый элемент DOM, вы должны создать из него jQuery-объект, заключив его в $ (и).

Мой проходящий Jasmine-jQuery-test наконец-то выглядит примерно так (используя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 ) )

Таким образом, «$ (this)» из моего кода Javascript переводится в «$ (DOM_input_element)» в моем тесте Jasmine-jQuery.

Надеюсь, это поможет вамваши проекты!Мне понадобилось много времени, чтобы понять это.

...