jstub is a lightweight javascript stubbing framework. jstub has no dependencies, although it will leverage
qunit if available. The jstub_tests.html
file, which uses jquery and qunit to run, is the best place to look for real world usage example.
You stub a method call via the $.stub
function. In its simplest form, $.stub
is called with 4 parameters.
The first is the object in which the function is define (global function live in @code@window@code@), the string name of the method, an array of expected parameters, and a return value. For example, say we wanted to test the following function:
//the internal implementation doesn't matter since we are mocking the getNewNotifications method function getNewNotifications(level) { var count = TODO;//hit the server and return the number of new notifications return count; }
We would call:
$.stub(window, 'getNewNotifications', [1], 10);
Any subsequent calls to getNewNotifications(1);
would return 10.
Stubbing a method that does not exist globally is equally as easy. Given:
$.blockUI = { show: function(text) { //todo block the UI return $blockElement; } }
We would call:
$.stub($.blockUI, 'show', ['Processing, Please Wait'], $('<div>'));
Passing a parameter of $.jstub.any
will create a wildcard match for a parameter:
$.stub(window, 'someFunction', [1, $.jstub.any, 'somethingElse'], 'was stubbed!'); someFunction(1, null, 'somethingElse); //will return 'was stubbed!' someFunction(1, 213, 'somethingElse); //will return 'was stubbed!' someFunction(1, new Object(), 'somethingElse); //will return 'was stubbed!'
Furthermore, you can match any parameters by specifying $.jstub.anyAll
:
$.stub(window, 'someFunction', $.jstub.anyAll, 'was stubbed!'); someFunction(1, null, null); //will return 'was stubbed!' someFunction(null, null, null); //will return 'was stubbed!' someFunction({}, {}, {}); //will return 'was stubbed!'
In the case where your method expects a single parameter (be it a simple value, or a more complex one), you do not have to pass the expected parameters in as an array:
$.stub($, 'post', {url: '/some/url', ...}, 'was stubbed!');
Rather than having a stub return a value, you can make it invoke a callback from the original list of arguments. To do say the returnValue
argument turns into the parameters to pass into the callback, and a new argument is added to specify the callback argument index. Think of the $.post
and $.get
jquery ajax method:
function doDelete(id) { $.post('/url/delete', {id: id}, function(response, status) { $('tr[rel=' + response.deletedId + ']').remove(); }, 'json'); }
In order to accurately stub our code we want to stub $.post
yet make sure the callback is properly executed:
$.stub($, 'post', ['/url/delete', {id: 1}, $.jstub.any, 'json'], [1, 'ok'], 2); doDelete(1); ok($('tr[rel=1]').length == 0, "row was deleted");
In the above example the returnValue
(the 4th argument to $.stub
) will be passed to our callback. And the
callback that’ll be executed is the 2 (0-based) parameter of the original (unstubbed) call.
In some cases your callback will be embedded in an object literal – such as when you use the $.ajax method. Stubbing such a scenario requires one additional parameter – the name:
$.stub($, 'ajax', {url: '/url/delete', data:{id: 1}, success: $.jstub.any}, 'deleted response!!', 0, 'success'); doDelete(1);
If a match cannot be found for a method which is being stubbed, an error will be thrown. If qunit is installed, a failed assertion with a error message will be displayed. If qunit is not installed, an exception will be raised.
All stubs can be reset by calling $.resetStubs()
jstub supports limited support for expectation checking. $.stub
returns an object which has an invoked
member which can be queried to count the number of times it was called:
var stub = $.stub($.blockUI, 'show', ['please wait'], null); $.blockUI.show('please wait'); $.blockUI.show('something else'); $.blockUI.show('please wait');
The stub.invoked
will be equal to 2
jstub has been tested on IE 6, firefox 3.6 and Chrome 6.