Spying on JQuery Selectors in Jasmine

I am testing JavaScript code with Jasmine and want to track (mock) the DOM element accessed by the jQuery selector.

My specification:

it("should be able to mock DOM call", function() { spyOn($("#Something"), 'val').andReturn("bar"); result = $("#Something").val(); expect(result).toEqual("bar"); }); 

In my specrunner.html, I have:

 <input type="hidden" id="Something" value="foo" /> 

Sorry, spec malfunction:

should be able to make fun of the DOM call The expected "foo" equal to "bar".

+52
jquery unit-testing jasmine
Mar 17 2018-11-11T00:
source share
6 answers

This line is incorrect:

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

The Jasmine spyOn function expects two parameters. The first is an existing object. The second is the name of the function as a string. You correctly pass the function name as a string ("val"), but you do not pass the existing object as the first parameter.

 $("#Something") 

... is not an existing object. This is the result (return value) of the jQuery selector. More specifically, it will return a jQuery object representing the matched nodes - like an array of results.

 $ 

... is an existing object.

 $.fn 

... is an existing object.

 $("#Something") 

... a non- existing object is the result of a jQuery selector.

This will work:

 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"); }); 
+85
Jun 01 '11 at 8:11
source share

Looks like I found a good solution.

  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') 

This is not based on your code, but I hope this can help someone. And, yes, an example in CoffeScript.

+27
Nov 20 '11 at 20:45
source share

The problem is that two calls to $ return two different nodes wrapped in jQuery.

This should work:

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

The next time, help is more common on the Jasmine mailing list: jasmine-js@googlegroups.com.

+15
Mar 23 2018-11-11T00:
source share

I wrote a helper function that takes an array of 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]; } } }) } } 

Each pair tells the faker function for which id whose value should be returned if the jQuery-val () function is called using the id selector. It is used as follows:

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

If $('#id1').val() is called in the function being tested, the fake function returns value1 , if $('#id2').val() , it returns value2 . Therefore, you do not need to bother with the DOM, you just mock the jQuery-val () function and model the return values. Other jQuery functions can probably mock the same way.

+2
Jan 25 '13 at 20:07
source share

You can create your own fake DOM element and then use $ ('# elementid') [0] as usual

 addFakeElementWithId = function (elementId) { var fake = document.createElement("div"); fake.setAttribute("id", elementId); document.body.appendChild(fake); }; 
+2
Feb 19 '13 at 20:22
source share

I think there are changes in my version of jasmine (2.0.3), so Alex York's solution does not work as it is, but it definitely gave me a way. So, here is a working spec jquery code that needs to be tested

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

here is part of the jasmine spectrum

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

A more granular specification may use a different layout level as

 spyOn(mockJqueryObject,"enable") spyOn(mockJqueryObject,"disable") 
+1
Aug 6 '15 at 7:16
source share



All Articles