Шпионаж на JQuery Селекторы в Жасмин
Я тестирую код 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".
Ответы
Ответ 1
Эта строка неверна:
spyOn($("#Something"), 'val').andReturn("bar");
Функция Jasmine spyOn ожидает два параметра. Первый - это существующий объект. Второй - это имя функции в виде строки. Вы правильно передаете имя функции в виде строки ( "val" ), но вы не передаете существующий объект в качестве первого параметра.
$("#Something")
... не является существующим объектом. Это результат (возвращаемое значение) селектора jQuery. Более конкретно, он вернет объект jQuery, представляющий согласованные узлы - вроде массива результатов.
$
... - это существующий объект.
$.fn
... - это существующий объект.
$("#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");
});
Ответ 2
Похоже, я нашел хорошее решение
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.
Ответ 3
Проблема в том, что два вызова $возвращают два разных узла, обернутых 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: [email protected]
Ответ 4
Я написал вспомогательную функцию, которая принимает массив пар 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];
}
}
})
}
}
Каждая пара сообщает функции faker, для которой id, значение которой должно быть возвращено, если функция jQuery-val() вызывается с помощью селектора id. Он используется следующим образом:
jasminTestHelper.spyOnValAndFake([["id1", "value1"], ["id2", "value2"]]);
Если в тестируемой функции вызывается $('#id1').val()
, функция fake возвращает value1
, если вызывается $('#id2').val()
, она возвращает value2
. Поэтому вам не нужно возиться с DOM, вы просто издеваетесь над функцией jQuery-val() и моделируете возвращаемые значения. Другие функции jQuery могут, вероятно, издеваться над тем же способом.
Ответ 5
Вы можете создать свой собственный поддельный элемент DOM, а затем использовать $('# elementid') [0] как обычно
addFakeElementWithId = function (elementId) {
var fake = document.createElement("div");
fake.setAttribute("id", elementId);
document.body.appendChild(fake);
};
Ответ 6
Я думаю, что в моей версии jasmine (2.0.3) есть изменения, поэтому решение Alex York не работает так, как есть, но определенно дало мне путь. Итак, вот рабочая спецификация Код 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")