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
</a>
Sinon.JSStandalone and test framework agnostic JavaScript test spies, stubs and mocks (pronounced "sigh-non", named after [Sinon, the warrior](https://en.wikipedia.org/wiki/Sinon)).Compatibility
For details on compatibility and browser support, please see COMPATIBILITY.md
Installation
via npm
$ npm install sinonor 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 () {} };
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
What is a test spy?
A test spy is a function that records arguments, return value, the value ofthis 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);
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");
},
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();
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();
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();
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'sargs 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:
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.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();
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 theonCall 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 ---
- Files Extracted: 5
- Estimated Token Budget: ~2735 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/sinonjs/sinon