How to mock jQuery with jasmine?

How can I verify that a specific jQuery selector has been launched with Jasmine? I am trying to do the following:

spyOn($.fn, 'init').andCallThrough(); // my code expect($.init).toHaveBeenCalled(); 

But after this call, $('div') returns Object { selector="div", context=document, NaN=div.spec, more...} , although it should return (and $.fn.init('div') returns it): [div.jasmine_reporter, div.banner, div.logo, 4 more...] . This stuff naturally breaks the code, because the jQuery object can no longer be used.

Example:

Let's say I want to check that the jQuery selector has been called, I write:

  it('tests', function() { spyOn($.fn, 'init').andCallThrough(); $('html'); expect($.init).toHaveBeenCalled(); }); 

The result is an error from Jasmine: Error: Expected a spy, but got undefined. . Then I set a breakpoint in FireBug in the line $ ('html'), and when I get there and try to see what the value of $('html') , I get:

 Object { selector="html", context=document, NaN=html, more...} 

If I comment on spyOn , this line of $('html') will say:

 [html] 

This is what I expected to see with spyOn .

+4
source share
1 answer

Well, it looks like Jasmine is doing this spy stuff, replacing the spire object with a wrapped version, and this is similar to jQuery in general, because (from jQuery source code):

// The jQuery object is actually just the constructor for the init constructor "extended"

I suggest trying to keep track of one of the functions that init uses, in particular, "merge". If you look at jQuery code, you will see that any HTML => DOM stuff ultimately returns through a merge call:

 return jQuery.merge( this, selector ); 

(this line is 152 if you are looking at jQuery 1.5.1 source).

By monitoring the merge, you should be able to test everything you test without accidentally replacing jQuery guts.

+3
source

All Articles