Следите за селектором JQuery в Жасмин - PullRequest
60 голосов
/ 17 марта 2011

Я тестирую немного JavaScript с Jasmine и хочу шпионить (макетировать) элемент DOM, к которому обращается селектор jQuery.

Моя спецификация:

it("should be able to mock DOM call", function() {

    spyOn($("#Something"), 'val').andReturn("bar");

    result = $("#Something").val();

    expect(result).toEqual("bar");

});

В моем specrunner.html у меня есть:

<input type="hidden" id="Something" value="foo" />

К сожалению, спецификация не работает с:

должна быть в состоянии смоделировать вызов DOM Ожидаемый 'foo' равным 'bar'.

Ответы [ 6 ]

93 голосов
/ 01 июня 2011

Эта строка неверна:

spyOn($("#Something"), 'val').andReturn("bar");

Функция spyOn Жасмина ожидает два параметра.Первый - это существующий объект.Второе - это имя функции в виде строки.Вы правильно передаете имя функции в виде строки («val»), но не передаете существующий объект в качестве первого параметра.

$("#Something")

... не является существующим объектом.Это результат (возвращаемое значение) селектора jQuery.Более конкретно, он вернет объект jQuery, представляющий совпавшие узлы - вроде как массив результатов.

$

... - это существующий объект.

$.fn

...is - существующий объект.

$("#Something")

... - это , а не существующий объект - это результат селектора jQuery .

Это будет работать:

it("should be able to mock DOM call", function () {
    //spyOn($.fn, "val").andReturn("bar"); //pre-jasmine 2.0 syntax
    spyOn($.fn, "val").and.returnValue("bar"); //Jasmine 2.0 Syntax
    var result = $("#Something").val();
    expect(result).toEqual("bar");
});
27 голосов
/ 21 ноября 2011

Похоже, я нашел хорошее решение

    it "should open past statuses", ->
      # We can't use $('.past') here cause each time $('.past') called it returns different objects
      # so we need to store spy in variable
      showSpy = spyOn($.fn, 'show')
      # do the stuff
      $('.show-past').click()
      # then check if 'show' action was called
      expect($.fn.show).toHaveBeenCalled()
      # and if it realy our object
      expect(showSpy.mostRecentCall.object.selector).toEqual('.past')

Это не основано на вашем коде, но я надеюсь, что это может кому-то помочь.И, да, пример в CoffeScript.

16 голосов
/ 23 марта 2011

Проблема состоит в том, что два вызова $ возвращают два разных jQuery-обернутых узла.

Это должно работать:

it("should be able to mock DOM call", function(){

  // var node = $("Something");
  // spyOn(node, 'val').andReturn('bar');

  // expect(node.val()).toEqual('bar');
  var node = $("Something");
  spyOn(node, 'val').and.returnValue('bar');

  expect(node.val()).toEqual('bar');
});

В следующий раз справка будет более распространена в рассылке Jasmineсписок: jasmine-js@googlegroups.com.

3 голосов
/ 20 февраля 2013

Вы можете создать свой собственный поддельный элемент DOM и затем использовать $ ('# elementid') [0] как обычно

addFakeElementWithId = function (elementId) {
      var fake = document.createElement("div");
      fake.setAttribute("id", elementId);
      document.body.appendChild(fake);
   };
2 голосов
/ 26 января 2013

Я написал вспомогательную функцию, которая принимает массив пар id / value.

var jasminTestHelper = {
    spyOnValAndFake : function(obj) {
        var i, j;
        spyOn($.fn, 'val').andCallFake(function() {
            for ( i = 0, j = obj.length; i < j; i++) {
                if (this.selector === '#' + obj[i][0]) {
                    return obj[i][1];
                }
            }
        })
    }
}

Каждая пара сообщает фейкер-функции, для какого идентификатора, какое значение должно быть возвращено, если функция jQuery-val () вызывается с помощью селектора id.Он используется следующим образом:

jasminTestHelper.spyOnValAndFake([["id1", "value1"], ["id2", "value2"]]);

Если в тестируемой функции вызывается $('#id1').val(), то фальшивая функция возвращает value1, если вызывается $('#id2').val(), возвращается value2.Так что вам не нужно возиться с DOM, вы просто издеваетесь над функцией jQuery-val () и моделируете возвращаемые значения.Другие jQuery-функции, вероятно, могут быть смоделированы таким же образом.

1 голос
/ 06 августа 2015

Я думаю, что в моей версии жасмина (2.0.3) произошли изменения, поэтому решение Алекса Йорка не сработало как есть, но определенно дало мне путь.Итак, вот код jquery рабочей спецификации, который должен быть протестирован

$('someSelector').data('someAttribute').enable();

, вот его часть спецификации жасмина

var mockJqueryObject = { enable:function(){},disable:function(){}};
//this mocks the .data('someAttribute') in above code.
spyOn($.fn, "data").and.returnValue(mockSelectBoxObject); 

Более детальная спецификация может использовать другой уровень насмешки как

spyOn(mockJqueryObject,"enable")
spyOn(mockJqueryObject,"disable")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...