Spying on JQuery Selectors in Jasmine
Solution 1:
This line is wrong:
spyOn($("#Something"), 'val').andReturn("bar");
Jasmine's spyOn function expects two parameters. The first is an existing object. The second is a function name as a string. You are correctly passing in the function name as a string ("val") but you are not passing in an existing object as the first parameter.
$("#Something")
...is not an existing object. It is the result (the return value) of a jQuery selector. More specifically, it will return a jQuery object representing the matched nodes - kind of like an array of results.
$
...is an existing object.
$.fn
...is an existing object.
$("#Something")
...is not an existing object - it 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");
});
Solution 2:
Seems like I found 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, example in CoffeScript.
Solution 3:
The problem is that the two calls to $ return two different jQuery-wrapped nodes.
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');
});
Next time, help is more prevalent on the Jasmine mailing list: [email protected].
Solution 4:
You could 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);
};