All free skills / Other majors

sinon 22.x

Use Sinon ^22.0.0 for standalone spies, stubs, fake timers, sandboxes, and Sinon assertions.

For
sinon@22.1.0
Verified
2026-09-08, 8 examples executed
Skill package
@modootoday/pmcp-sinon@22.0.0

Use this skill for free

No PMCP login or subscription is required. Download the original instructions, or install the content-only archive with your project's package manager.

Download SKILL.md · Download package archive

npm install --save-dev https://pmcp.build/skills/sinon/22/package.tgz

PMCP discovers the installed package's instructions. Connect your runtime after installation.

Archive integritysha512-wyQDl22vNlrTh0hrsOt7AgeGlxE/oKNLxIfiz5L45Zw4w8ZAYWCBh8zp37Vn1q/KDUSPS1kTQGKCib1JD8H2oA==

Complete instructions

Verified against sinon@22.1.0 on 2026-09-08. 8 of 8 examples executed.

Sinon ^22.0.0

Import and version-specific shape

Sinon 22 supports both CommonJS and ESM through the package root. ESM consumers can use:

import sinon from "sinon";
import assert from "node:assert/strict";

assert.equal(typeof sinon.spy, "function");
assert.equal(typeof sinon.stub, "function");

The older, commonly copied CommonJS form remains valid because the package provides a CommonJS require condition:

const sinon = require("sinon");

Do not infer from Sinon’s ESM source migration that require("sinon") stopped working. The ESM migration occurred in 21.1.0; Sinon 22 retains the CommonJS package entry.

Sinon is a library, not a test runner. A plain script has no injected describe, it, or expect; use Node’s assertions or sinon.assert directly.

Spies

Use sinon.spy() for a callable that records calls, sinon.spy(fn) to wrap a function, or sinon.spy(object, "method") to wrap an existing method. A property can also be spied on with the documented third types argument.

Useful recorded data includes callCount, called, calledOnce, args, firstCall, lastCall, returnValues, and thisValues. Useful checks and accessors include calledWith, calledWithExactly, calledBefore, calledAfter, getCall, getCalls, returned, threw, and withArgs.

When a spy replaces an object method, restore it when finished. resetHistory() clears call history but does not restore the original method; restore() restores the wrapped method.

import sinon from "sinon";
import assert from "node:assert/strict";

const object = {
  greet(name: string) {
    return `Hello, ${name}`;
  }
};

const spy = sinon.spy(object, "greet");
assert.equal(object.greet("Ada"), "Hello, Ada");
assert.equal(spy.callCount, 1);
assert.equal(spy.calledOnce, true);
assert.deepEqual(spy.firstCall.args, ["Ada"]);
assert.equal(spy.calledWithExactly("Ada"), true);
assert.equal(spy.returned("Hello, Ada"), true);

spy.resetHistory();
assert.equal(spy.callCount, 0);
spy.restore();
assert.equal(object.greet("Grace"), "Hello, Grace");

Stubs

Use sinon.stub() for a standalone stub or sinon.stub(object, "method") to replace an object method. Configure behavior with returns, throws, resolves, rejects, callsFake, callsThrough, returnsThis, value, get, onCall, and argument-specific withArgs behavior. yield, yields, and yieldsAsync configure callback behavior.

Per-call configuration is ordered: onCall(0) applies to the first call, onCall(1) to the second, and so on. A default such as returns(...) handles calls not otherwise configured. Restore replaced methods after use.

wrappedMethod is the wrapped original method on a stub created from an object method. callsThrough() delegates to that original implementation, while callsFake() replaces behavior.

import sinon from "sinon";
import assert from "node:assert/strict";

const stub = sinon.stub();
stub.onCall(0).returns("Apple pie");
stub.onCall(1).returns("Blueberry pie");
stub.returns("Raspberry pie");

assert.equal(stub(), "Apple pie");
assert.equal(stub(), "Blueberry pie");
assert.equal(stub(), "Raspberry pie");
assert.equal(stub.callCount, 3);

const asyncStub = sinon.stub();
asyncStub.resolves("done");
assert.equal(await asyncStub(), "done");

const object = {
  value() {
    return 7;
  }
};
const methodStub = sinon.stub(object, "value").throws(new Error("blocked"));
assert.throws(() => object.value(), /blocked/);
methodStub.restore();
assert.equal(object.value(), 7);

Fake timers

Use sinon.useFakeTimers() to replace timer behavior with a controllable clock. Schedule work, advance with tick, and call restore() when finished. The clock also documents countTimers, jump, next, nextAsync, now, reset, runAll, runMicrotasks, runToFrame, runToLast, setSystemTime, and tick.

next() advances to and fires the first scheduled timer. nextAsync() additionally allows scheduled promise callbacks to run, so use it when testing timer callbacks that enqueue asynchronous work.

import sinon from "sinon";
import assert from "node:assert/strict";

const clock = sinon.useFakeTimers();
let calls = 0;
setTimeout(() => {
  calls += 1;
}, 500);

assert.equal(clock.countTimers(), 1);
clock.tick(499);
assert.equal(calls, 0);
clock.tick(1);
assert.equal(calls, 1);
clock.restore();
import sinon from "sinon";
import assert from "node:assert/strict";

const clock = sinon.useFakeTimers();
const events: string[] = [];
setTimeout(() => {
  events.push("timer");
  Promise.resolve().then(() => events.push("promise"));
}, 10);

await clock.nextAsync();
assert.deepEqual(events, ["timer", "promise"]);
clock.restore();

Sandboxes

sinon.createSandbox() creates an isolated alternative to the default sandbox on the sinon object. Keep the sandbox and call sandbox.restore() during cleanup so spies, stubs, and other replacements do not leak into later work.

A sandbox can also inject selected APIs into an object. injectInto selects the target object and properties selects the APIs to inject.

import sinon from "sinon";
import assert from "node:assert/strict";

const object = {
  greet() {
    return "original";
  }
};
const sandbox = sinon.createSandbox();
const spy = sandbox.spy(object, "greet");

assert.equal(object.greet(), "original");
assert.equal(spy.calledOnce, true);
sandbox.restore();
assert.equal(object.greet(), "original");
import sinon from "sinon";
import assert from "node:assert/strict";

const facade: { spy?: typeof sinon.spy } = {};
const sandbox = sinon.createSandbox({
  injectInto: facade,
  properties: ["spy"]
});
const object = { run() {} };
const spy = facade.spy!(object, "run");
object.run();
assert.equal(spy.calledOnce, true);
sandbox.restore();

Assertions and matchers

Sinon assertions are available under sinon.assert. Documented callable members include fail(message), match(actual, expectation), and expose(target, options). Spy assertions include calledOnce and calledWith.

sinon.assert.match(actual, expectation) performs the assertion directly. It is not a matcher object whose .test() method should be called.

import sinon from "sinon";
import assert from "node:assert/strict";

const spy = sinon.spy();
spy("message");
sinon.assert.calledOnce(spy);
sinon.assert.calledWith(spy, "message");

sinon.assert.match({ role: "admin", active: true }, { role: "admin" });
assert.throws(
  () => sinon.assert.match({ role: "user" }, { role: "admin" }),
  /expected value to match/
);

sinon.assert.expose(target, { prefix: "" }) exposes Sinon assertion methods on the supplied assertion object without a name prefix. Use this only when deliberately extending another assertion API; otherwise call sinon.assert directly. The exposed assertion API is primarily useful when integrating with a test or assertion tool; such integration is exercised by that tool rather than by a bare script.

Cleanup and compatibility

Restore every replaced method and every fake clock. Prefer a sandbox when a task creates several doubles, since one sandbox.restore() cleans up the sandbox-managed replacements.

Sinon 22 targets modern runtimes moving toward ES2023 and requires no transpiler or polyfills in supporting runtimes. Older runtimes may require a transpiler supplied by the dependent project; the compatibility research suggests Sinon 9 for older browsers.

Sinon’s source repository relies on generated artifacts for normal package and test workflows. This skill assumes the published package is installed; it does not describe rebuilding Sinon from its repository.

Not covered

This skill does not cover Sinon’s complete API, every spy/stub method overload, browser bundler configuration, repository build commands, test-runner integration, older Sinon major versions, or runtime-specific transpiler/polyfill setup beyond the compatibility boundary described above.