0
# Assertions
1
2
Sinon's assertion methods provide a comprehensive way to test spy, stub, and mock behavior with clear, descriptive error messages. They integrate well with any testing framework and offer more readable alternatives to manual spy property checking.
3
4
## Capabilities
5
6
### Basic Call Assertions
7
8
Assert whether spies/stubs were called and how many times.
9
10
```javascript { .api }
11
declare namespace assert {
12
/**
13
* Assert that spy was called at least once
14
* @param spy - Spy to check
15
* @throws AssertionError if spy was never called
16
*/
17
function called(spy: SinonSpy): void;
18
19
/**
20
* Assert that spy was never called
21
* @param spy - Spy to check
22
* @throws AssertionError if spy was called
23
*/
24
function notCalled(spy: SinonSpy): void;
25
26
/**
27
* Assert that spy was called exactly once
28
* @param spy - Spy to check
29
* @throws AssertionError if spy was not called exactly once
30
*/
31
function calledOnce(spy: SinonSpy): void;
32
33
/**
34
* Assert that spy was called exactly twice
35
* @param spy - Spy to check
36
* @throws AssertionError if spy was not called exactly twice
37
*/
38
function calledTwice(spy: SinonSpy): void;
39
40
/**
41
* Assert that spy was called exactly three times
42
* @param spy - Spy to check
43
* @throws AssertionError if spy was not called exactly three times
44
*/
45
function calledThrice(spy: SinonSpy): void;
46
47
/**
48
* Assert that spy was called a specific number of times
49
* @param spy - Spy to check
50
* @param count - Expected call count
51
* @throws AssertionError if call count doesn't match
52
*/
53
function callCount(spy: SinonSpy, count: number): void;
54
}
55
```
56
57
**Usage Examples:**
58
59
```javascript
60
import { assert } from "sinon";
61
62
const spy = sinon.spy();
63
64
// Test that function wasn't called initially
65
assert.notCalled(spy);
66
67
// Call the spy
68
spy();
69
70
// Test that it was called
71
assert.called(spy);
72
assert.calledOnce(spy);
73
74
// Call again
75
spy();
76
77
// Test specific count
78
assert.calledTwice(spy);
79
assert.callCount(spy, 2);
80
```
81
82
### Argument Assertions
83
84
Assert that spies/stubs were called with specific arguments.
85
86
```javascript { .api }
87
declare namespace assert {
88
/**
89
* Assert that spy was called with specific arguments (partial match)
90
* @param spy - Spy to check
91
* @param args - Arguments that should be present
92
* @throws AssertionError if spy was never called with these arguments
93
*/
94
function calledWith(spy: SinonSpy, ...args: any[]): void;
95
96
/**
97
* Assert that spy was called with exact arguments (exact match)
98
* @param spy - Spy to check
99
* @param args - Exact arguments expected
100
* @throws AssertionError if spy was never called with exactly these arguments
101
*/
102
function calledWithExactly(spy: SinonSpy, ...args: any[]): void;
103
104
/**
105
* Assert that spy was called with arguments matching patterns
106
* @param spy - Spy to check
107
* @param matchers - Matcher patterns for arguments
108
* @throws AssertionError if spy was never called with matching arguments
109
*/
110
function calledWithMatch(spy: SinonSpy, ...matchers: any[]): void;
111
112
/**
113
* Assert that spy was always called with specific arguments
114
* @param spy - Spy to check
115
* @param args - Arguments that should be in every call
116
* @throws AssertionError if any call didn't include these arguments
117
*/
118
function alwaysCalledWith(spy: SinonSpy, ...args: any[]): void;
119
120
/**
121
* Assert that spy was always called with exact arguments
122
* @param spy - Spy to check
123
* @param args - Exact arguments expected in every call
124
* @throws AssertionError if any call didn't have exactly these arguments
125
*/
126
function alwaysCalledWithExactly(spy: SinonSpy, ...args: any[]): void;
127
128
/**
129
* Assert that spy was always called with matching arguments
130
* @param spy - Spy to check
131
* @param matchers - Matcher patterns for every call
132
* @throws AssertionError if any call didn't match patterns
133
*/
134
function alwaysCalledWithMatch(spy: SinonSpy, ...matchers: any[]): void;
135
136
/**
137
* Assert that spy was never called with specific arguments
138
* @param spy - Spy to check
139
* @param args - Arguments that should never be present
140
* @throws AssertionError if spy was ever called with these arguments
141
*/
142
function neverCalledWith(spy: SinonSpy, ...args: any[]): void;
143
144
/**
145
* Assert that spy was never called with matching arguments
146
* @param spy - Spy to check
147
* @param matchers - Matcher patterns that should never match
148
* @throws AssertionError if spy was ever called with matching arguments
149
*/
150
function neverCalledWithMatch(spy: SinonSpy, ...matchers: any[]): void;
151
}
152
```
153
154
**Usage Examples:**
155
156
```javascript
157
const spy = sinon.spy();
158
159
spy("hello", "world");
160
spy("foo", { bar: "baz" });
161
162
// Test specific arguments
163
assert.calledWith(spy, "hello");
164
assert.calledWith(spy, "hello", "world");
165
assert.calledWithExactly(spy, "hello", "world");
166
167
// Test with matchers
168
import { match } from "sinon";
169
assert.calledWithMatch(spy, "foo", match.object);
170
assert.calledWithMatch(spy, match.string, { bar: "baz" });
171
172
// Test that certain arguments were never used
173
assert.neverCalledWith(spy, "invalid");
174
```
175
176
### Context Assertions
177
178
Assert the `this` context and constructor usage of spy calls.
179
180
```javascript { .api }
181
declare namespace assert {
182
/**
183
* Assert that spy was called with specific `this` context
184
* @param spy - Spy to check
185
* @param thisValue - Expected `this` value
186
* @throws AssertionError if spy was never called with this context
187
*/
188
function calledOn(spy: SinonSpy, thisValue: any): void;
189
190
/**
191
* Assert that spy was always called with specific `this` context
192
* @param spy - Spy to check
193
* @param thisValue - Expected `this` value for all calls
194
* @throws AssertionError if any call didn't use this context
195
*/
196
function alwaysCalledOn(spy: SinonSpy, thisValue: any): void;
197
198
/**
199
* Assert that spy was called as a constructor (with `new`)
200
* @param spy - Spy to check
201
* @throws AssertionError if spy was never called with `new`
202
*/
203
function calledWithNew(spy: SinonSpy): void;
204
205
/**
206
* Assert that spy was always called as a constructor
207
* @param spy - Spy to check
208
* @throws AssertionError if any call didn't use `new`
209
*/
210
function alwaysCalledWithNew(spy: SinonSpy): void;
211
}
212
```
213
214
**Usage Examples:**
215
216
```javascript
217
const context = { name: "test" };
218
const spy = sinon.spy();
219
220
// Call with specific context
221
spy.call(context, "arg");
222
223
// Assert context
224
assert.calledOn(spy, context);
225
226
// Constructor testing
227
function TestConstructor() {}
228
const constructorSpy = sinon.spy(TestConstructor);
229
230
new TestConstructor();
231
assert.calledWithNew(constructorSpy);
232
```
233
234
### Special Call Assertions
235
236
Assert specific call scenarios like once with exact arguments.
237
238
```javascript { .api }
239
declare namespace assert {
240
/**
241
* Assert that spy was called once and with exact arguments
242
* @param spy - Spy to check
243
* @param args - Expected exact arguments for the single call
244
* @throws AssertionError if spy wasn't called exactly once with these exact arguments
245
*/
246
function calledOnceWithExactly(spy: SinonSpy, ...args: any[]): void;
247
248
/**
249
* Assert that spy was called once and with matching arguments
250
* @param spy - Spy to check
251
* @param matchers - Matcher patterns for the single call
252
* @throws AssertionError if spy wasn't called exactly once with matching arguments
253
*/
254
function calledOnceWithMatch(spy: SinonSpy, ...matchers: any[]): void;
255
}
256
```
257
258
**Usage Examples:**
259
260
```javascript
261
const spy = sinon.spy();
262
263
spy("exact", "arguments");
264
265
// Assert single call with exact arguments
266
assert.calledOnceWithExactly(spy, "exact", "arguments");
267
268
// With matchers
269
const spy2 = sinon.spy();
270
spy2("test", { key: "value" });
271
272
assert.calledOnceWithMatch(spy2, match.string, match.object);
273
```
274
275
### Exception Assertions
276
277
Assert that spies/stubs threw exceptions.
278
279
```javascript { .api }
280
declare namespace assert {
281
/**
282
* Assert that spy threw an exception
283
* @param spy - Spy to check
284
* @param error - Optional specific error to check for
285
* @throws AssertionError if spy never threw (the specified) exception
286
*/
287
function threw(spy: SinonSpy, error?: any): void;
288
289
/**
290
* Assert that spy always threw an exception
291
* @param spy - Spy to check
292
* @param error - Optional specific error to check for
293
* @throws AssertionError if spy didn't always throw (the specified) exception
294
*/
295
function alwaysThrew(spy: SinonSpy, error?: any): void;
296
}
297
```
298
299
**Usage Examples:**
300
301
```javascript
302
const stub = sinon.stub();
303
stub.throws(new TypeError("Invalid argument"));
304
305
try {
306
stub();
307
} catch (e) {
308
// Exception expected
309
}
310
311
// Assert that exception was thrown
312
assert.threw(stub);
313
assert.threw(stub, "TypeError");
314
assert.threw(stub, new TypeError("Invalid argument"));
315
```
316
317
### Call Order Assertions
318
319
Assert the order in which multiple spies were called.
320
321
```javascript { .api }
322
declare namespace assert {
323
/**
324
* Assert that spies were called in the specified order
325
* @param spies - Spies in expected call order
326
* @throws AssertionError if spies were not called in this order
327
*/
328
function callOrder(...spies: SinonSpy[]): void;
329
}
330
```
331
332
**Usage Examples:**
333
334
```javascript
335
const spy1 = sinon.spy();
336
const spy2 = sinon.spy();
337
const spy3 = sinon.spy();
338
339
// Call in specific order
340
spy1();
341
spy2();
342
spy3();
343
spy1(); // Can be called again
344
345
// Assert order
346
assert.callOrder(spy1, spy2, spy3);
347
```
348
349
### Matcher Assertions
350
351
Assert values match specific patterns using Sinon's matcher system.
352
353
```javascript { .api }
354
declare namespace assert {
355
/**
356
* Assert that actual value matches the expected pattern
357
* @param actual - Actual value to test
358
* @param matcher - Matcher pattern or expected value
359
* @throws AssertionError if value doesn't match pattern
360
*/
361
function match(actual: any, matcher: any): void;
362
}
363
```
364
365
**Usage Examples:**
366
367
```javascript
368
import { assert, match } from "sinon";
369
370
// Test values against matchers
371
assert.match("hello", match.string);
372
assert.match(42, match.number);
373
assert.match({ name: "test" }, match.object);
374
assert.match({ name: "test" }, match.has("name"));
375
376
// Complex matching
377
const user = { id: 1, name: "John", age: 25 };
378
assert.match(user, {
379
id: match.number,
380
name: match.string,
381
age: match.greaterThan(18)
382
});
383
```
384
385
### Utility Assertions
386
387
Utility methods for test success and failure.
388
389
```javascript { .api }
390
declare namespace assert {
391
/**
392
* Explicitly fail an assertion with a message
393
* @param message - Failure message
394
* @throws AssertionError with the provided message
395
*/
396
function fail(message?: string): void;
397
398
/**
399
* Explicitly pass an assertion (for test runners that track passes)
400
* @param message - Optional pass message
401
*/
402
function pass(message?: string): void;
403
}
404
```
405
406
**Usage Examples:**
407
408
```javascript
409
// Conditional assertion
410
if (someCondition) {
411
assert.pass("Condition met");
412
} else {
413
assert.fail("Expected condition to be true");
414
}
415
```
416
417
### Configuring Assertions
418
419
Expose assertion methods on testing framework objects.
420
421
```javascript { .api }
422
declare namespace assert {
423
/**
424
* Expose assertion methods on a target object
425
* @param target - Object to add assertion methods to
426
* @param options - Configuration for exposed methods
427
*/
428
function expose(target: any, options?: {
429
prefix?: string;
430
includeFail?: boolean;
431
}): void;
432
}
433
```
434
435
**Usage Examples:**
436
437
```javascript
438
// Expose on test context (e.g., Mocha's `this`)
439
beforeEach(function() {
440
sinon.assert.expose(this, { prefix: "should" });
441
});
442
443
it("should test spy behavior", function() {
444
const spy = sinon.spy();
445
spy();
446
447
// Now you can use this.shouldHaveBeenCalled instead of assert.called
448
this.shouldHaveBeenCalled(spy);
449
this.shouldHaveBeenCalledOnce(spy);
450
});
451
```
452
453
### Integration with Testing Frameworks
454
455
Examples of using assertions with popular testing frameworks.
456
457
**Usage Examples:**
458
459
```javascript
460
// Mocha integration
461
describe("User service", () => {
462
let userService, apiSpy;
463
464
beforeEach(() => {
465
apiSpy = sinon.spy(api, "fetch");
466
});
467
468
afterEach(() => {
469
sinon.restore();
470
});
471
472
it("should fetch user data", async () => {
473
await userService.getUser(1);
474
475
sinon.assert.calledOnce(apiSpy);
476
sinon.assert.calledWith(apiSpy, "/users/1");
477
});
478
});
479
480
// Jest integration (can also use Jest's expect)
481
test("should call callback", () => {
482
const callback = sinon.spy();
483
const service = new Service(callback);
484
485
service.process("data");
486
487
sinon.assert.calledOnce(callback);
488
sinon.assert.calledWith(callback, "data");
489
});
490
```
491
492
## Types
493
494
```javascript { .api }
495
interface SinonAssert {
496
// Basic call assertions
497
called(spy: SinonSpy): void;
498
notCalled(spy: SinonSpy): void;
499
calledOnce(spy: SinonSpy): void;
500
calledTwice(spy: SinonSpy): void;
501
calledThrice(spy: SinonSpy): void;
502
callCount(spy: SinonSpy, count: number): void;
503
504
// Argument assertions
505
calledWith(spy: SinonSpy, ...args: any[]): void;
506
calledWithExactly(spy: SinonSpy, ...args: any[]): void;
507
calledWithMatch(spy: SinonSpy, ...matchers: any[]): void;
508
alwaysCalledWith(spy: SinonSpy, ...args: any[]): void;
509
alwaysCalledWithExactly(spy: SinonSpy, ...args: any[]): void;
510
alwaysCalledWithMatch(spy: SinonSpy, ...matchers: any[]): void;
511
neverCalledWith(spy: SinonSpy, ...args: any[]): void;
512
neverCalledWithMatch(spy: SinonSpy, ...matchers: any[]): void;
513
514
// Context assertions
515
calledOn(spy: SinonSpy, thisValue: any): void;
516
alwaysCalledOn(spy: SinonSpy, thisValue: any): void;
517
calledWithNew(spy: SinonSpy): void;
518
alwaysCalledWithNew(spy: SinonSpy): void;
519
520
// Special assertions
521
calledOnceWithExactly(spy: SinonSpy, ...args: any[]): void;
522
calledOnceWithMatch(spy: SinonSpy, ...matchers: any[]): void;
523
524
// Exception assertions
525
threw(spy: SinonSpy, error?: any): void;
526
alwaysThrew(spy: SinonSpy, error?: any): void;
527
528
// Order assertions
529
callOrder(...spies: SinonSpy[]): void;
530
531
// Matcher assertions
532
match(actual: any, matcher: any): void;
533
534
// Utility
535
fail(message?: string): void;
536
pass(message?: string): void;
537
expose(target: any, options?: { prefix?: string; includeFail?: boolean }): void;
538
}
539
```