监视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调用Expected \'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 /值对。
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,如果使用id选择器调用jQuery-val()函数,则应返回哪个值。它的用法如下:
jasminTestHelper.spyOnValAndFake([[\"id1\", \"value1\"], [\"id2\", \"value2\"]]);
如果在被测函数中调用
$(\'#id1\').val()
,则伪函数返回
value1
,如果调用called15ѭ,则返回
value2
。因此,您无需摆弄DOM,只需模拟jQuery-val()函数并模拟返回值即可。其他jQuery函数可能以相同的方式嘲笑。     
        我认为我的茉莉花版本(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\")
    

要回复问题请先登录注册