sinonjs.org Open in urlscan Pro
2606:50c0:8001::153  Public Scan

URL: https://sinonjs.org/
Submission: On February 21 via api from US — Scanned from US

Form analysis 0 forms found in the DOM

Text Content

Sinon.JS
 * Documentation
 * Releases
 * How To
 * 


STANDALONE TEST SPIES, STUBS AND MOCKS FOR JAVASCRIPT.
WORKS WITH ANY UNIT TESTING FRAMEWORK.

Get Started Star Sinon.JS on Github

Proudly Sponsored By


Become a sponsor and get your logo on our README on GitHub with a link to your
site

Proudly Backed By


Become a backer and support Sinon.JS with a monthly donation.


GET STARTED


INSTALL USING NPM

To install the current release (v17.0.1) of Sinon:

npm install sinon



SETTING UP ACCESS

NODE AND COMMONJS BUILD SYSTEMS

var sinon = require("sinon");


DIRECT BROWSER USE

<script src="./node_modules/sinon/pkg/sinon.js"></script>
<script>
  // Access the `sinon` global...
</script>


Or in an ES6 Modules environment (modern browsers only)

<script type="module">
  import sinon from "./node_modules/sinon/pkg/sinon-esm.js";
</script>



TRY IT OUT

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;
  };
}



FAKES

Testing this function can be quite elegantly achieved with a test fake:

it("calls the original function", function () {
  var callback = sinon.fake();
  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.fake();
  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.fake();
  var proxy = once(callback);
  var obj = {};

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

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


Learn more about fakes.


BEHAVIOR

The function returned by once should return whatever the original function
returns. To test this, we create a fake with behavior:

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

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


Conveniently, we can query fakes for their callCount, received args and more.

Learn more about fakes.


TESTING AJAX

The following function triggers network activity:

function getTodos(listId, callback) {
  jQuery.ajax({
    url: "/todo/" + listId + "/items",
    success: function (data) {
      // Node-style CPS: callback(err, data)
      callback(null, data);
    },
  });
}


A unit test should not actually trigger a function’s network activity. To test
getTodos() without triggering its network activity, use the sinon.replace()
method to replace the jQuery.ajax method in your test. Restore the jQuery.ajax
method after your test by calling sinon.restore() in your test runner’s after()
function.

after(function () {
  sinon.restore();
});

it("makes a GET request for todo items", function () {
  sinon.replace(jQuery, "ajax", sinon.fake());

  getTodos(42, sinon.fake());

  assert(jQuery.ajax.calledWithMatch({ url: "/todo/42/items" }));
});



FAKE XMLHTTPREQUEST

While the preceding test shows off some nifty Sinon.JS tricks, it is too tightly
coupled to the implementation. When testing Ajax, it is better to use Sinon.JS’
fake XMLHttpRequest:

var xhr, requests;

before(function () {
  xhr = sinon.useFakeXMLHttpRequest();
  requests = [];
  xhr.onCreate = function (req) {
    requests.push(req);
  };
});

after(function () {
  // Like before we must clean up when tampering with globals.
  xhr.restore();
});

it("makes a GET request for todo items", function () {
  getTodos(42, sinon.fake());

  assert.equals(requests.length, 1);
  assert.match(requests[0].url, "/todo/42/items");
});


Learn more about fake XMLHttpRequest.


FAKE SERVER

The preceding example shows how flexible this API is. If it looks too laborious,
you may like the fake server:

var server;

before(function () {
  server = sinon.fakeServer.create();
});
after(function () {
  server.restore();
});

it("calls callback with deserialized data", function () {
  var callback = sinon.fake();
  getTodos(42, callback);

  // This is part of the FakeXMLHttpRequest API
  server.requests[0].respond(
    200,
    { "Content-Type": "application/json" },
    JSON.stringify([{ id: 1, text: "Provide examples", done: true }]),
  );

  assert(callback.calledOnce);
});


Test framework integration can typically reduce boilerplate further. Learn more
about the fake server.


FAKING TIME

> “I don’t always bend time and space in unit tests, but when I do, I use
> Buster.JS + Sinon.JS”

Brian Cavalier, Cujo.JS

Testing time-sensitive logic without the wait is a breeze with Sinon.JS. The
following function debounces another function - only when it has not been called
for 100 milliseconds will it call the original function with the last set of
arguments it received.

function debounce(callback) {
  var timer;
  return function () {
    clearTimeout(timer);
    var args = [].slice.call(arguments);
    timer = setTimeout(function () {
      callback.apply(this, args);
    }, 100);
  };
}


Thanks to Sinon.JS’ time-bending abilities, testing it is easy:

var clock;

before(function () {
  clock = sinon.useFakeTimers();
});
after(function () {
  clock.restore();
});

it("calls callback after 100ms", function () {
  var callback = sinon.fake();
  var throttled = debounce(callback);

  throttled();

  clock.tick(99);
  assert(callback.notCalled);

  clock.tick(1);
  assert(callback.calledOnce);

  // Also:
  // assert.equals(new Date().getTime(), 100);
});


As before, Sinon.JS provides utilities that help test frameworks reduce the
boiler-plate. Learn more about fake time.


AND ALL THE REST…

You’ve seen the most common tasks people tackle with Sinon.JS, yet we’ve only
scratched the surface. View more quick examples below, or dive into the API
docs, which also provides useful pointers on how and when to use the various
functionality.


GET HELP

 * Stack Overflow
 * IRC: #sinon.js on freenode


SINON.JS ELSEWHERE

 * Testing Backbone applications with Jasmine and Sinon
 * Sinon.JS fake server live demo

Christian Johansen’s book Test-Driven JavaScript Development covers some of the
design philosophy and initial sketches for Sinon.JS.



Join the discussion on Stack Overflow!

All copyright is reserved the Sinon committers.

Released under the BSD license.