web-dev-qa-db-ja.com

JasmineでのJQueryセレクターのスパイ

私はいくつかのJavaScriptをJasmineで単体テストし、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」に等しいと予想されます。

60
Daniel Elliott

この行は間違っています:

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

JasmineのspyOn関数は2つのパラメーターを想定しています。最初は既存のオブジェクトです。 2番目は文字列としての関数名です。関数名を文字列( "val")として正しく渡しますが、既存のオブジェクトを最初のパラメーターとして渡しません。

$("#Something")

...は既存のオブジェクトではありません。 jQueryセレクターの結果(戻り値)です。より具体的には、一致したノードを表すjQueryオブジェクトを返します-一種の結果の配列のようなものです。

$

...は既存のオブジェクトです。

$.fn

...は既存のオブジェクトです。

$("#Something")

...はnot既存のオブジェクトです-それは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");
});
93
Alex York

良い解決策を見つけたようです

    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の例です。

27
hoblin

問題は、$への2つの呼び出しが2つの異なる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]でヘルプがより一般的になります。

16
user588542

独自の偽のDOM要素を作成し、通常どおり$( '#elementid')[0]を使用できます。

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

Id/value-pairsの配列を受け入れるヘルパー関数を作成しました。

_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-selectorで呼び出された場合にどのidに対してどの値が返されるべきかをfaker-functionに伝えます。次のように使用されます。

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

テスト対象の関数で$('#id1').val()が呼び出された場合、fake-functionは_value1_を返し、$('#id2').val()が呼び出された場合は_value2_を返します。したがって、DOMをいじる必要はなく、jQuery-val()関数をモックし、戻り値をシミュレートするだけです。他のjQuery関数もおそらく同じようにモックできます。

2
Roland Würth

私のジャスミンバージョン(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")
1
Sanjay Bharwani