All notes
Sinonjs

Sinon

Standalone test spies, stubs and mocks for JavaScript.

sinonjs.org.

A test example

The following function takes a function as its argument and returns a new function. You can call the resulting function as many times as you want, but the original function will only be called once:


function once(fn) {
    var returnValue, called = false;
    return function () {
        if (!called) {
            called = true;
            returnValue = fn.apply(this, arguments);
        }
        return returnValue;
    };
}

Spies

sinonJS.org: spies.

Creating a spy as an anonymous function



"test should call subscribers on publish": function () {
    var callback = sinon.spy();
    PubSub.subscribe("message", callback);
    PubSub.publishSync("message");
    assertTrue(callback.called);
}

Using a spy to wrap an existing method



{
    setUp: function () {
        sinon.spy(jQuery, "ajax");
    },

    tearDown: function () {
        jQuery.ajax.restore(); // Unwraps the spy
    },

    "test should inspect jQuery.getJSON's usage of jQuery.ajax": function () {
        jQuery.getJSON("/some/resource");

        assert(jQuery.ajax.calledOnce);
        assertEquals("/some/resource", jQuery.ajax.getCall(0).args[0].url);
        assertEquals("json", jQuery.ajax.getCall(0).args[0].dataType);
    }
}

// Ensure it calls the function.
it('calls the original function', function () {
    var callback = sinon.spy();
    var proxy = once(callback);

    proxy();

    assert(callback.called);
});

// The fact that the function was only called once is important:
it('calls the original function only once', function () {
    var callback = sinon.spy();
    var proxy = once(callback);

    proxy();
    proxy();

    assert(callback.calledOnce);
    // ...or:
    // assert.equals(callback.callCount, 1);
});

// We also care about the this value and arguments:
it('calls original function with right this and args', function () {
    var callback = sinon.spy();
    var proxy = once(callback);
    var obj = {};

    proxy.call(obj, 1, 2, 3);

    assert(callback.calledOn(obj));
    assert(callback.calledWith(1, 2, 3));
});

Stubs



it("returns the return value from the original function", function () {
    var callback = sinon.stub().returns(42);
    var proxy = once(callback);

    assert.equals(proxy(), 42);
});

Conveniently, stubs can also be used as spies, e.g. we can query them for their callCount, received args and more.