Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i stub $(window).width() using Sinon?

I have a function in JS view which performs some action if the window width is less than 1000. I'm attempting to write unit tests for this with Mocha, chai and running the tests via karma test runner in Phantom/Chrome/Chromium browser.

I also use sinon to stub the methods and making it to return some desired value. Now there is a condition check where if the window width is less than 1000 so how can i stub this, i was trying something like below,

sinon.stub($(window).width());
$(window).width().returns(900);

But it is not working. Is there any specific way where i can stub $(window).width() value?

like image 837
Sai Avatar asked Jun 03 '15 18:06

Sai


1 Answers

sinon.stub() usage:

First: you're not passing methods/functions to sinon.stub() correctly. Here's the correct way to do it:

sinon.stub(object, 'method');

Where object is an object whose method you want to stub, 'method' is a string containing the name of this method.

Another way is to simply overwrite current function with a stub, calling .stub() with no arguments:

object.method = sinon.stub();

Taking that into account, let's move on to your current code.

Current code:

sinon.stub($(window).width());

As I wrote above - this is an incorrect call to sinon.stub().

Putting that aside, you're approaching it from the wrong angle. You cannot stub $(window).width() - $(window).width() isn't a function, it's a call to a function - returning a number (here: width of the window in px). That's the value you would actually be trying to replace with a stub - arbitrary primitive (number), not even bound to any variable.

Next try:

sinon.stub($(window), 'width');

Now, why this wouldn't work?

We're only stubbing width method on this specific jQuery object - but each call to $(...) creates a new one. Here's the result:

var $window = $(window);
sinon.stub($window, 'width').returns(900);

$window.width(); // 900 - using .width() method stub
$(window).width(); // real window width - new jQuery object

(jsfiddle: http://jsfiddle.net/xqco8u77/ )

Solution

Stub the .width() method on prototype of jQuery objects - whose methods/values are available globally for each jQuery object.

sinon.stub($.prototype, 'width').returns(900);

// "900"
$(window).width();

// restoring original function
$.prototype.width.restore();

// real window width
$(window).width();

Working demo on jsfiddle: http://jsfiddle.net/gjcguvzh/5/

(As you can see, I've also restored original .width() prototype method after using the stub, in case you have to make use of it later.)

like image 61
bardzusny Avatar answered Sep 19 '22 14:09

bardzusny