0
# Sinon.js
1
2
Sinon.js is a comprehensive JavaScript testing library providing standalone test spies, stubs, and mocks. It offers framework-agnostic test doubles for creating robust unit tests, enabling developers to intercept function calls, control return values, and verify interactions without modifying the original codebase.
3
4
## Package Information
5
6
- **Package Name**: sinon
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install sinon`
10
11
## Core Imports
12
13
```javascript
14
import sinon from "sinon";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const sinon = require("sinon");
21
```
22
23
Individual imports:
24
25
```javascript
26
import { spy, stub, mock, fake, assert, match, createSandbox, createStubInstance } from "sinon";
27
```
28
29
## Basic Usage
30
31
```javascript
32
import sinon from "sinon";
33
34
// Create a spy to track calls
35
const callback = sinon.spy();
36
callback("hello", "world");
37
console.log(callback.calledWith("hello", "world")); // true
38
39
// Create a stub with behavior
40
const fetchData = sinon.stub().resolves({ data: "test" });
41
const result = await fetchData();
42
console.log(result); // { data: "test" }
43
44
// Mock an object method
45
const user = { getName: () => "original" };
46
const mock = sinon.mock(user);
47
mock.expects("getName").once().returns("mocked");
48
49
console.log(user.getName()); // "mocked"
50
mock.verify(); // Passes - expectation met
51
mock.restore();
52
```
53
54
## Architecture
55
56
Sinon.js is built around several key components:
57
58
- **Sandbox**: Isolated test environment managing all fakes and providing cleanup
59
- **Spies**: Record function calls, arguments, and return values without changing behavior
60
- **Stubs**: Spies with programmable behavior for controlling return values and side effects
61
- **Mocks**: Pre-programmed expectations for verifying specific interactions
62
- **Fakes**: Lightweight alternative providing spy functionality with optional implementations
63
- **Fake Timers**: Control time-dependent code by mocking timers and Date
64
- **Assertions**: Testing utilities for verifying spy/stub/mock behavior
65
- **Matchers**: Flexible argument matching for complex assertions
66
67
## Capabilities
68
69
### Sandbox Management
70
71
Isolated testing environment that manages all fakes and provides automatic cleanup. Essential for test isolation and preventing test interference.
72
73
```javascript { .api }
74
function createSandbox(options?: SandboxOptions): SinonSandbox;
75
76
interface SinonSandbox {
77
spy(): SinonSpy;
78
spy<F extends Function>(func: F): SinonSpy<F>;
79
spy<T>(object: T, method: keyof T): SinonSpy;
80
81
stub(): SinonStub;
82
stub<T>(object: T, method: keyof T): SinonStub;
83
84
mock(object: any): SinonMock;
85
fake(func?: Function): SinonFake;
86
87
restore(): void;
88
reset(): void;
89
resetBehavior(): void;
90
resetHistory(): void;
91
}
92
93
interface SandboxOptions {
94
injectInto?: object;
95
properties?: string[];
96
useFakeTimers?: boolean | FakeTimerConfig;
97
useFakeServer?: boolean;
98
}
99
```
100
101
[Sandbox Management](./sandbox.md)
102
103
### Test Spies
104
105
Record function calls, arguments, return values, and exceptions without changing the original function's behavior. Perfect for verifying function interactions.
106
107
```javascript { .api }
108
function spy(): SinonSpy;
109
function spy<F extends Function>(func: F): SinonSpy<F>;
110
function spy<T>(object: T, method: keyof T): SinonSpy;
111
112
interface SinonSpy {
113
called: boolean;
114
callCount: number;
115
calledOnce: boolean;
116
calledTwice: boolean;
117
calledThrice: boolean;
118
119
calledWith(...args: any[]): boolean;
120
calledWithExactly(...args: any[]): boolean;
121
alwaysCalledWith(...args: any[]): boolean;
122
123
firstCall: SinonSpyCall;
124
lastCall: SinonSpyCall;
125
getCall(index: number): SinonSpyCall;
126
getCalls(): SinonSpyCall[];
127
}
128
```
129
130
[Test Spies](./spies.md)
131
132
### Test Stubs
133
134
Spies with programmable behavior for controlling return values, exceptions, and callback execution. Ideal for isolating code under test from dependencies.
135
136
```javascript { .api }
137
function stub(): SinonStub;
138
function stub<T>(object: T, method: keyof T): SinonStub;
139
140
interface SinonStub extends SinonSpy {
141
returns(value: any): SinonStub;
142
throws(error?: any): SinonStub;
143
resolves(value?: any): SinonStub;
144
rejects(error?: any): SinonStub;
145
146
callsFake(func: Function): SinonStub;
147
callsThrough(): SinonStub;
148
149
yields(...args: any[]): SinonStub;
150
callsArg(index: number): SinonStub;
151
152
withArgs(...args: any[]): SinonStub;
153
onCall(index: number): SinonStub;
154
onFirstCall(): SinonStub;
155
}
156
```
157
158
[Test Stubs](./stubs.md)
159
160
### Test Mocks
161
162
Pre-programmed expectations for verifying specific method calls and their parameters. Excellent for testing precise interaction contracts.
163
164
```javascript { .api }
165
function mock(object: any): SinonMock;
166
167
interface SinonMock {
168
expects(method: string): SinonExpectation;
169
restore(): void;
170
verify(): void;
171
}
172
173
interface SinonExpectation {
174
once(): SinonExpectation;
175
twice(): SinonExpectation;
176
thrice(): SinonExpectation;
177
exactly(count: number): SinonExpectation;
178
atLeast(count: number): SinonExpectation;
179
atMost(count: number): SinonExpectation;
180
181
withArgs(...args: any[]): SinonExpectation;
182
returns(value: any): SinonExpectation;
183
throws(error?: any): SinonExpectation;
184
}
185
```
186
187
[Test Mocks](./mocks.md)
188
189
### Fake Functions
190
191
Lightweight alternative to spies providing call recording with optional custom implementations. Simpler than stubs for basic testing scenarios.
192
193
```javascript { .api }
194
function fake(func?: Function): SinonFake;
195
196
// Static creation methods
197
declare namespace fake {
198
function returns(value: any): SinonFake;
199
function throws(error?: any): SinonFake;
200
function resolves(value?: any): SinonFake;
201
function rejects(error?: any): SinonFake;
202
function yields(...args: any[]): SinonFake;
203
}
204
205
interface SinonFake extends SinonSpy {
206
// Inherits all spy properties and methods
207
}
208
```
209
210
[Fake Functions](./fakes.md)
211
212
### Fake Timers
213
214
Control time-dependent code by mocking JavaScript's timing functions (setTimeout, setInterval) and Date constructor. Essential for testing time-based logic.
215
216
```javascript { .api }
217
function useFakeTimers(config?: FakeTimerConfig): SinonClock;
218
219
interface SinonClock {
220
tick(milliseconds: number): void;
221
next(): void;
222
runAll(): void;
223
runToLast(): void;
224
225
restore(): void;
226
227
Date: DateConstructor;
228
setTimeout: typeof setTimeout;
229
clearTimeout: typeof clearTimeout;
230
setInterval: typeof setInterval;
231
clearInterval: typeof clearInterval;
232
}
233
234
interface FakeTimerConfig {
235
now?: number | Date;
236
toFake?: string[];
237
shouldAdvanceTime?: boolean;
238
advanceTimeDelta?: number;
239
}
240
```
241
242
[Fake Timers](./timers.md)
243
244
### Assertions
245
246
Comprehensive assertion methods for testing spy, stub, and mock behavior. Provides clear error messages for failed expectations.
247
248
```javascript { .api }
249
declare namespace assert {
250
function called(spy: SinonSpy): void;
251
function notCalled(spy: SinonSpy): void;
252
function calledOnce(spy: SinonSpy): void;
253
function calledTwice(spy: SinonSpy): void;
254
function calledThrice(spy: SinonSpy): void;
255
256
function calledWith(spy: SinonSpy, ...args: any[]): void;
257
function calledWithExactly(spy: SinonSpy, ...args: any[]): void;
258
function alwaysCalledWith(spy: SinonSpy, ...args: any[]): void;
259
260
function threw(spy: SinonSpy, error?: any): void;
261
function callOrder(...spies: SinonSpy[]): void;
262
}
263
```
264
265
[Assertions](./assertions.md)
266
267
### Argument Matching
268
269
Flexible argument matching system for creating sophisticated test assertions and stub behaviors. Supports type-based, property-based, and custom matchers.
270
271
```javascript { .api }
272
declare namespace match {
273
// Type matchers
274
const any: SinonMatcher;
275
const bool: SinonMatcher;
276
const number: SinonMatcher;
277
const string: SinonMatcher;
278
const object: SinonMatcher;
279
const func: SinonMatcher;
280
const array: SinonMatcher;
281
282
// Value matchers
283
function same(value: any): SinonMatcher;
284
function typeOf(type: string): SinonMatcher;
285
function instanceOf(constructor: Function): SinonMatcher;
286
287
// Property matchers
288
function has(property: string, value?: any): SinonMatcher;
289
function hasOwn(property: string, value?: any): SinonMatcher;
290
291
// Custom matchers
292
function (predicate: (value: any) => boolean, message?: string): SinonMatcher;
293
}
294
295
interface SinonMatcher {
296
and(matcher: SinonMatcher): SinonMatcher;
297
or(matcher: SinonMatcher): SinonMatcher;
298
}
299
```
300
301
[Argument Matching](./matchers.md)
302
303
### Class Instance Stubbing
304
305
Create stubbed instances of constructors with all methods replaced by stubs. Essential for testing code that depends on class instances without invoking the real constructor.
306
307
```javascript { .api }
308
function createStubInstance<T>(
309
constructor: SinonStubCreateStubInstanceConstructor<T>,
310
overrides?: SinonStubbedInstance<T>
311
): SinonStubbedInstance<T>;
312
313
type SinonStubbedInstance<T> = T & {
314
[K in keyof T]: T[K] extends Function ? SinonStub : T[K];
315
};
316
```
317
318
### Promise Utilities
319
320
Controllable Promise implementation for testing asynchronous code without relying on timing or external Promise resolution.
321
322
```javascript { .api }
323
function promise<T = any>(executor?: PromiseExecutor<T>): SinonPromise<T>;
324
325
interface SinonPromise<T> extends Promise<T> {
326
status: "pending" | "resolved" | "rejected";
327
resolvedValue?: T;
328
rejectedValue?: any;
329
resolve(value?: T): SinonPromise<T>;
330
reject(reason?: any): Promise<void>;
331
}
332
```
333
334
[Promise Utilities](./promises.md)
335
336
### Custom Behaviors
337
338
Extend stub functionality by adding custom behavior methods. Allows creating reusable stub patterns and domain-specific testing utilities.
339
340
```javascript { .api }
341
function addBehavior(name: string, fn: Function): void;
342
```
343
344
**Usage Examples:**
345
346
```javascript
347
import sinon from "sinon";
348
349
// Add a custom behavior for returning promises
350
sinon.addBehavior("returnsPromise", function(fake, value) {
351
fake.returns(Promise.resolve(value));
352
});
353
354
// Add a custom behavior for delayed responses
355
sinon.addBehavior("returnsAfterDelay", function(fake, value, delay) {
356
fake.returns(new Promise(resolve => {
357
setTimeout(() => resolve(value), delay);
358
}));
359
});
360
361
// Add a behavior for sequential returns
362
sinon.addBehavior("returnsSequentially", function(fake, ...values) {
363
values.forEach((value, index) => {
364
fake.onCall(index).returns(value);
365
});
366
});
367
368
// Use the custom behaviors
369
const apiStub = sinon.stub();
370
apiStub.returnsPromise({ data: "test" });
371
372
const delayedStub = sinon.stub();
373
delayedStub.returnsAfterDelay("delayed result", 100);
374
375
const sequentialStub = sinon.stub();
376
sequentialStub.returnsSequentially("first", "second", "third");
377
378
// Test the behaviors
379
console.log(await apiStub()); // { data: "test" }
380
console.log(sequentialStub()); // "first"
381
console.log(sequentialStub()); // "second"
382
console.log(sequentialStub()); // "third"
383
```
384
385
## Types
386
387
```javascript { .api }
388
interface SinonSpyCall {
389
args: any[];
390
thisValue: any;
391
returnValue: any;
392
exception: Error;
393
394
calledWith(...args: any[]): boolean;
395
calledWithExactly(...args: any[]): boolean;
396
returned(value: any): boolean;
397
threw(error?: any): boolean;
398
}
399
400
// Global sinon object extends SinonSandbox
401
interface SinonStatic extends SinonSandbox {
402
createSandbox(options?: SandboxOptions): SinonSandbox;
403
createStubInstance<T>(
404
constructor: SinonStubCreateStubInstanceConstructor<T>,
405
overrides?: SinonStubbedInstance<T>
406
): SinonStubbedInstance<T>;
407
match: typeof match;
408
assert: typeof assert;
409
restoreObject(object: any): void;
410
411
// Additional top-level exports
412
expectation: SinonExpectation;
413
timers: any; // From @sinonjs/fake-timers
414
addBehavior(name: string, fn: Function): void;
415
promise<T = any>(executor?: PromiseExecutor<T>): SinonPromise<T>;
416
}
417
```