Sinon.JS

Standalone test spies, stubs and mocks for JavaScript. No dependencies, works with any unit testing framework.

2012-04-16 - Changelog - Source code - Documentation

What does Sinon.JS look like?

"test should call subscriber": function () {
    var spy = sinon.spy();

    PubSub.subscribe("message", spy);
    PubSub.publishSync("message", undefined);

    assertTrue(spy.called);
}

Spy documentation. Example is a modified test from Morgan Roderick's PubSubJS.

"test should call all subscribers when exceptions": function () {
    var spy = sinon.spy();
    var stub = sinon.stub().throws("Error");

    PubSub.subscribe("message", stub);
    PubSub.subscribe("message", spy);

    PubSub.publishSync("message", undefined);

    assertTrue(stub.called);
    assertTrue(spy.called);
}

Stub documentation. Example is a modified test from Morgan Roderick's PubSubJS.

"test should call subscriber": function () {
    var myAPI = { method: function () {} };

    var mock = sinon.mock(myAPI);
    mock.expects("method").once();

    PubSub.subscribe("message", myAPI.method);
    PubSub.publishSync("message", undefined);

    mock.verify();
}

Mock documentation. Example is a modified test from Morgan Roderick's PubSubJS.

{
    setUp: function () {
        this.clock = sinon.useFakeTimers();
    },

    tearDown: function () {
        this.clock.restore();
    },

    "test should animate element over 500ms" : function(){
        var el = jQuery("<div></div>");
        el.appendTo(document.body);

        el.animate({ height: "200px", width: "200px" });
        this.clock.tick(510);

        assertEquals("200px", el.css("height"));
        assertEquals("200px", el.css("width"));
    }
}

Timers documentation

{
    setUp: function () {
        this.xhr = sinon.useFakeXMLHttpRequest();
        var requests = this.requests = [];

        this.xhr.onCreate = function (xhr) {
            requests.push(xhr);
        };
    },

    tearDown: function () {
        this.xhr.restore();
    },

    "test should fetch comments from server" : function () {
        var callback = sinon.spy();
        myLib.getCommentsFor("/some/article", callback);
        assertEquals(1, this.requests.length);

        this.requests[0].respond(200, { "Content-Type": "application/json" },
                                 '[{ "id": 12, "comment": "Hey there" }]');
        assert(callback.calledWith([{ id: 12, comment: "Hey there" }]));
    }
}

Fake XHR/server documentation

{
    setUp: function () {
        this.server = sinon.fakeServer.create();
    },

    tearDown: function () {
        this.server.restore();
    },

    "test should fetch comments from server" : function () {
        this.server.respondWith("GET", "/some/article/comments.json",
                                [200, { "Content-Type": "application/json" },
                                 '[{ "id": 12, "comment": "Hey there" }]']);

        var callback = sinon.spy();
        myLib.getCommentsFor("/some/article", callback);
        this.server.respond();

        assert(callback.calledWith([{ id: 12, comment: "Hey there" }]));
    }
}

Fake XHR/server documentation

Example is a modified test from Morgan Roderick's PubSubJS.

"test using sinon.test sandbox": sinon.test(function () {
    var myAPI = { method: function () {} };
    sinon.mock(myAPI).expects("method").once();

    PubSub.subscribe("message", myAPI.method);
    PubSub.publishSync("message", undefined);
})

Sandbox documentation

Example is a modified test from Morgan Roderick's PubSubJS.

"test should call subscribers with message as first argument" : function () {
    var message = getUniqueString();
    var spy = sinon.spy();

    PubSub.subscribe(message, spy);
    PubSub.publishSync(message, "some payload");

    sinon.assert.calledOnce(spy);
    sinon.assert.calledWith(spy, message);
}

Assertions documentation

Documentation

What's new in 1.3.0?

What's new in 1.1.0?

Test framework adapters

Get help

Sinon.JS elsewhere

My book, Test-Driven JavaScript Development covers some of the design philosophy and initial sketches for Sinon.JS.

Sinon uses Semantic versioning.

Copyright 2010 - 2012, Christian Johansen. Released under the BSD license.