Program Tip

Jasmine에서 JQuery 선택기 감시

programtip 2020. 12. 3. 19:11
반응형

Jasmine에서 JQuery 선택기 감시


Jasmine으로 일부 JavaScript를 단위 테스트 중이며 jQuery 선택기가 액세스하는 DOM 요소를 감시 (모의)하고 싶습니다.

내 사양은 다음과 같습니다.

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'와 같습니다.


이 줄은 잘못되었습니다.

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");
});

좋은 해결책을 찾은 것 같습니다

    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의 예입니다.


문제는 $에 대한 두 번의 호출이 두 개의 다른 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)에 도움이 더 많이 있습니다.


자신 만의 가짜 DOM 요소를 만든 다음 평소처럼 $ ( '# elementid') [0]을 사용할 수 있습니다.

addFakeElementWithId = function (elementId) {
      var fake = document.createElement("div");
      fake.setAttribute("id", elementId);
      document.body.appendChild(fake);
   };

나는 id / value-pair의 배열을 받아들이는 helper-function을 작성했습니다.

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];
                }
            }
        })
    }
}

각 쌍은 어떤 id에 대한 faker-function을 알려줍니다. jQuery-val ()-function이 id-selector로 호출되면 어떤 값이 반환되어야하는지 알려줍니다. 다음과 같이 사용됩니다.

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

If $('#id1').val() is called in your function under test, the fake-function returns value1, if $('#id2').val() is called it returns value2. So you don't need to fiddle with the DOM, you just mock the jQuery-val()-function and simulate return-values. Other jQuery-functions could probably mocked the same way.


I think there is a change in my jasmine version (2.0.3), hence the solution by Alex York didn't work as is, but definitely gave me a path. So here is the working spec jquery code which is to be tested

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

here is the jasmine spec part of it

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

A more granular spec could use another level of mock as

spyOn(mockJqueryObject,"enable")
spyOn(mockJqueryObject,"disable")

참고URL : https://stackoverflow.com/questions/5337481/spying-on-jquery-selectors-in-jasmine

반응형