在茉莉花间谍jQueryselect器

我正在使用Jasmine对一些JavaScript进行unit testing,并希望窥探(模拟)jQueryselect器访问的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"); 

茉莉花的spyOn函数需要两个参数。 第一个是现有的对象。 第二个是作为一个string的函数名称。 您正确地将函数名称作为string(“val”)传递,但是您没有传入现有对象作为第一个参数。

 $("#Something") 

…不是现有的对象。 这是一个jQueryselect器的结果(返回值)。 更具体地说,它将返回一个代表匹配节点的jQuery对象 – 类似于结果数组。

 $ 

…是一个现有的对象。

 $.fn 

…是一个现有的对象。

 $("#Something") 

不是一个现有的对象 – 这是一个jQueryselect器的结果

这将工作:

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

似乎我find了很好的解决scheme

  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。

我写了一个帮助函数,它接受一个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]; } } }) } } 

每一对告诉faker函数哪个id,如果用idselect器调用jQuery-val()函数,应该返回哪个值。 它是这样使用的:

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

如果$('#id1').val()在被测函数中被调用,假函数返回value1 ,如果$('#id2').val()被调用,则返回value2 。 所以你不需要摆弄DOM,只需要模拟jQuery-val()函数并且模拟返回值。 其他的jQueryfunction也可能以同样的方式嘲弄。

您可以创build自己的假DOM元素,然后像往常一样使用$('#elementid')[0]

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

我认为我的茉莉花版本(2.0.3)有所改变,因此Alex York的解决scheme并不是如此,但肯定给了我一条道路。 所以这里是要testing的工作规范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")