sinon Documentation

Test spies, stubs and mocks for JavaScript.

RAW Doc

Technical Documentation: sinonjs/sinon

ℹ️ Provenance: Hybrid Fusion: sinonjs/sinon + sinonjs/sinon-docs Β· CodeWiki Reference Β· Recency: Active (< 180 days)

1. Project Overview & Quickstart (sinonjs/sinon)

text
</a>

Sinon.JS








Compatibility

For details on compatibility and browser support, please see COMPATIBILITY.md

Installation

via npm

text
$ npm install sinon

or via Sinon's browser builds available for download on the homepage.
There are also npm based CDNs one can use.

Usage

See the sinon project homepage for documentation on usage.

If you have questions that are not covered by the documentation, you can check out the sinon tag on Stack Overflow.

Goals

  • No global pollution
  • Easy to use
  • Require minimal β€œintegration”
  • Easy to embed seamlessly with any testing framework
  • Easily fake any interface
  • Ship with ready-to-use fakes for timers

Contribute?

See CONTRIBUTING.md for details on how you can contribute to Sinon.JS. Artifact-first contract tests are used to protect public APIs during migration.
The lib/ directory is generated build output and is not committed to the repository; run npm run build to regenerate it locally when needed.

Backers

Thank you to all our backers! πŸ™ [Become a backer]

Sponsors

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











Licence

Sinon.js was released under BSD-3

2. Official Technical Reference & Guides (sinonjs/sinon-docs)

File: README.md

sinon-docs

What you are looking for is here


File: resources/docs/mocks-intro.md

What are mocks?

Mocks (and mock expectations) are fake methods (like spies) with pre-programmed
behavior (like stubs) as well as pre-programmed expectations. A mock
will fail your test if it is not used as expected.

When to use mocks?

Mocks should only be used for the method under test. In every unit test, there
should be one unit under test. If you want to control how your unit is being
used and like stating expectations upfront (as opposed to asserting after the
fact), use a mock.

When to **not** use mocks?

Mocks come with built-in expectations that may fail your test. Thus, they
enforce implementation details. The rule of thumb is: if you wouldn't add an
assertion for some specific call, don't mock it. Use a stub instead. In general
you should never have more than one mock (possibly with several
expectations) in a single test.

Expectations implement both the spies and
stubs APIs.

To see how mocks look like in Sinon.JS, here's one of the PubSubJS tests again,
this time using a method as callback and using mocks to verify its behavior:

"test should call all subscribers when exceptions": function () {
var myAPI = { method: function () {} };

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

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

mock.verify();
assert(spy.calledOnce);

}


File: resources/docs/spies-intro.md

  • [sinon.spy()](#sinonspy)
  • [spy API](#spies-api)
  • [spy call API](#spycall)
  • What is a test spy?

    A test spy is a function that records arguments, return value, the value of
    this and exception thrown (if any) for all its calls. A test spy can be an
    anonymous function or it can wrap an existing function.

    When to use spies?

    Test spies are useful to test both callbacks and how certain functions/methods
    are used throughout the system under test. The following simplified example
    shows how to use spies to test how a function handles a callback:

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

    text
    PubSub.publishSync("message");
    
    assertTrue(callback.called);

    }

    Spying on existing methods

    sinon.spy can also spy on existing functions. When doing so, the original
    function will behave just as normal (including when used as a constructor) but
    you will have access to data about all calls. The following is a slightly
    contrived example:

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

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

    }

    Creating spies: `sinon.spy()`

    `var spy = sinon.spy();`
    Creates an anonymous function that records arguments, `this` value, exceptions and return values for all calls.
    `var spy = sinon.spy(myFunc);`
    Spies on the provided function
    `var spy = sinon.spy(object, "method");`
    Creates a [spy](#spyprops) for `object.method` and replaces the original method with the spy. The spy acts exactly like the original method in all cases. The original method can be restored by calling `object.method.restore()`. The returned spy is the function object which replaced the original method. `spy === object.method`.

    Spy API

    Spies provide a rich interface to inspect their usage. The above examples showed
    the calledOnce boolean property as well as the getCall method and the
    returned object's args property. There are three ways of inspecting call data.

    The preferred approach is to use the spy's calledWith method (and friends)
    because it keeps your test from being too specific about which call did what and
    so on. It will return true if the spy was ever called with the provided
    arguments.

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

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

    }

    If you want to be specific, you can directly check the first argument of the
    first call. There are two ways of achieving this:

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

    text
    PubSub.subscribe(message, spy);
    PubSub.publishSync(message, "some payload");
    
    assertEquals(message, spy.args[0][0]);

    }

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

    text
    PubSub.subscribe(message, spy);
    PubSub.publishSync(message, "some payload");
    
    assertEquals(message, spy.getCall(0).args[0]);

    }

    The first example uses the two-dimensional args array directly on the spy,
    while the second example fetches the first call object and then accesses it's
    args array. Which one to use is a matter of preference, but the recommended
    approach is going with spy.calledWith(arg1, arg2, ...) unless there's a need
    to make the tests highly specific.


    File: resources/docs/stubs-intro.md

    What are stubs?

    Test stubs are functions (spies) with pre-programmed behavior. They support the
    full test spy API in addition to methods which can be used
    to alter the stub's behavior.

    As spies, stubs can be either anonymous, or wrap existing functions. When
    wrapping an existing function with a stub, the original function is not called.

    When to use stubs?

    Use a stub when you want to:

    1. Control a method's behavior from a test to force the code down a specific
      path. Examples include forcing a method to throw an error in order to test
      error handling.

    2. When you want to prevent a specific method from being called directly
      (possibly because it triggers undesired behavior, such as a XMLHttpRequest or
      similar).

    The following example is yet another test from Morgan Roderick's PubSubJS which
    shows how to create an anonymous stub that throws an exception when called.

    "test should call all subscribers, even if there are exceptions" : function(){
    var message = 'an example message';
    var error = 'an example error message';
    var stub = sinon.stub().throws();
    var spy1 = sinon.spy();
    var spy2 = sinon.spy();

    text
    PubSub.subscribe(message, stub);
    PubSub.subscribe(message, spy1);
    PubSub.subscribe(message, spy2);
    
    PubSub.publishSync(message, undefined);
    
    assert(spy1.called);
    assert(spy2.called);
    assert(stub.calledBefore(spy1));

    }

    Note how the stub also implements the spy interface. The test verifies that all
    callbacks were called, and also that the exception throwing stub was called
    before one of the other callbacks.

    Defining stub behavior on consecutive calls

    Calling behavior defining methods like returns or throws multiple times
    overrides the behavior of the stub. As of Sinon version 1.8, you can use the
    onCall method to make a stub respond differently on
    consecutive calls.

    Note that in Sinon version 1.5 to version 1.7, multiple calls to the yields*
    and callsArg* family of methods define a sequence of behaviors for consecutive
    calls. As of 1.8, this functionality has been removed in favor of the onCall API.

    --- METRICS ---