63

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' に等しいと予想されます。

4

6 に答える 6

97

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

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

Jasmine の spyOn 関数は 2 つのパラメーターを必要とします。1 つ目は、既存のオブジェクトです。2 番目は文字列としての関数名です。関数名を文字列 ("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");
});
于 2011-06-01T08:11:01.773 に答える
27

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

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

于 2011-11-20T20:45:02.070 に答える
17

問題は、$ への 2 つの呼び出しが、jQuery でラップされた 2 つの異なるノードを返すことです。

これはうまくいくはずです:

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 でより多くのヘルプが提供されます。

于 2011-03-23T05:34:02.093 に答える
3

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

addFakeElementWithId = function (elementId) {
      var fake = document.createElement("div");
      fake.setAttribute("id", elementId);
      document.body.appendChild(fake);
   };
于 2013-02-19T20:22:21.540 に答える
2

ID/値ペアの配列を受け入れるヘルパー関数を作成しました。

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 セレクターを使用して jQuery-val() 関数が呼び出された場合に返される ID の値をフェイカー関数に通知します。次のように使用されます。

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

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

于 2013-01-25T20:07:30.827 に答える