0
# Fake Functions
1
2
Fake functions are a simpler alternative to spies and stubs, providing call recording with optional custom implementations. They offer most spy functionality with easier creation patterns for common testing scenarios.
3
4
## Capabilities
5
6
### Creating Fakes
7
8
Create fake functions with optional implementations.
9
10
```javascript { .api }
11
/**
12
* Creates a fake function that records calls
13
* @param func - Optional implementation function
14
* @returns Fake function with spy capabilities
15
*/
16
function fake(func?: Function): SinonFake;
17
```
18
19
**Usage Examples:**
20
21
```javascript
22
import { fake } from "sinon";
23
24
// Empty fake (no implementation)
25
const callback = fake();
26
callback("test");
27
console.log(callback.called); // true
28
29
// Fake with implementation
30
const add = fake((a, b) => a + b);
31
console.log(add(2, 3)); // 5
32
console.log(add.calledWith(2, 3)); // true
33
```
34
35
### Static Creation Methods
36
37
Convenient static methods for creating fakes with common behaviors.
38
39
```javascript { .api }
40
declare namespace fake {
41
/**
42
* Creates a fake that returns a specific value
43
* @param value - Value to return when called
44
* @returns Fake function that returns the value
45
*/
46
function returns(value: any): SinonFake;
47
48
/**
49
* Creates a fake that throws an exception
50
* @param error - Error to throw (creates generic Error if omitted)
51
* @returns Fake function that throws the error
52
*/
53
function throws(error?: any): SinonFake;
54
55
/**
56
* Creates a fake that returns a resolved Promise
57
* @param value - Value to resolve with
58
* @returns Fake function that resolves with the value
59
*/
60
function resolves(value?: any): SinonFake;
61
62
/**
63
* Creates a fake that returns a rejected Promise
64
* @param error - Error to reject with
65
* @returns Fake function that rejects with the error
66
*/
67
function rejects(error?: any): SinonFake;
68
69
/**
70
* Creates a fake that calls its first callback argument
71
* @param args - Arguments to pass to the callback
72
* @returns Fake function that yields to callback
73
*/
74
function yields(...args: any[]): SinonFake;
75
76
/**
77
* Creates a fake that calls its first callback argument asynchronously
78
* @param args - Arguments to pass to the callback
79
* @returns Fake function that yields to callback async
80
*/
81
function yieldsAsync(...args: any[]): SinonFake;
82
}
83
```
84
85
**Usage Examples:**
86
87
```javascript
88
// Fake that returns value
89
const getName = fake.returns("John");
90
console.log(getName()); // "John"
91
92
// Fake that throws error
93
const failingFunction = fake.throws(new Error("Operation failed"));
94
// failingFunction(); // throws Error: Operation failed
95
96
// Fake that resolves Promise
97
const fetchData = fake.resolves({ data: "success" });
98
const result = await fetchData();
99
console.log(result); // { data: "success" }
100
101
// Fake that rejects Promise
102
const failedFetch = fake.rejects(new Error("Network error"));
103
try {
104
await failedFetch();
105
} catch (error) {
106
console.log(error.message); // "Network error"
107
}
108
109
// Fake that calls callback
110
const processAsync = fake.yields(null, "processed");
111
processAsync((err, data) => {
112
console.log(data); // "processed"
113
});
114
115
// Fake that calls callback asynchronously
116
const processAsyncDelayed = fake.yieldsAsync("result");
117
processAsyncDelayed((data) => {
118
console.log(data); // "result" (called on next tick)
119
});
120
```
121
122
### Fake Properties and Methods
123
124
Fakes inherit all spy properties and methods for call verification.
125
126
```javascript { .api }
127
interface SinonFake extends SinonSpy {
128
// Inherits all spy properties:
129
// called, callCount, calledOnce, calledTwice, calledThrice
130
// firstCall, secondCall, thirdCall, lastCall
131
132
// Inherits all spy methods:
133
// calledWith, calledWithExactly, alwaysCalledWith, etc.
134
// calledOn, alwaysCalledOn, calledWithNew, etc.
135
// threw, alwaysThrew, returned, alwaysReturned
136
// getCall, getCalls, withArgs
137
// resetHistory, restore, printf
138
}
139
```
140
141
**Usage Examples:**
142
143
```javascript
144
const fake = sinon.fake();
145
146
fake("hello", "world");
147
fake("foo", "bar");
148
149
// Use all spy properties
150
console.log(fake.called); // true
151
console.log(fake.callCount); // 2
152
console.log(fake.calledTwice); // true
153
154
// Use spy methods
155
console.log(fake.calledWith("hello")); // true
156
console.log(fake.firstCall.args); // ["hello", "world"]
157
console.log(fake.getCall(1).args); // ["foo", "bar"]
158
159
// Filter calls
160
const helloFake = fake.withArgs("hello");
161
console.log(helloFake.callCount); // 1
162
```
163
164
### Fake vs Spy vs Stub Comparison
165
166
Understanding when to use fakes instead of spies or stubs.
167
168
**Usage Examples:**
169
170
```javascript
171
// Spy: Monitor existing function
172
const originalFn = (x) => x * 2;
173
const spy = sinon.spy(originalFn);
174
console.log(spy(5)); // 10 (original behavior)
175
176
// Stub: Replace function with programmable behavior
177
const stub = sinon.stub();
178
stub.withArgs("test").returns("result");
179
stub.withArgs("error").throws();
180
181
// Fake: Simple function with optional implementation
182
const fake = sinon.fake((x) => x + 1);
183
console.log(fake(5)); // 6
184
185
// Static fake creation (most convenient)
186
const quickFake = sinon.fake.returns("quick result");
187
console.log(quickFake()); // "quick result"
188
```
189
190
### Integration with Objects
191
192
Using fakes to replace object methods.
193
194
**Usage Examples:**
195
196
```javascript
197
// Replace object method with fake
198
const user = { getName: () => "John" };
199
user.getName = sinon.fake.returns("Jane");
200
201
console.log(user.getName()); // "Jane"
202
console.log(user.getName.called); // true
203
204
// Using in sandbox for automatic cleanup
205
const sandbox = sinon.createSandbox();
206
sandbox.replace(user, "getName", sinon.fake.returns("Mocked"));
207
208
console.log(user.getName()); // "Mocked"
209
sandbox.restore(); // Restores original method
210
```
211
212
### Testing Callbacks with Fakes
213
214
Fakes are particularly useful for testing callback-based code.
215
216
**Usage Examples:**
217
218
```javascript
219
// Test code that accepts callbacks
220
function processData(data, onSuccess, onError) {
221
if (data.valid) {
222
onSuccess(data.result);
223
} else {
224
onError(new Error("Invalid data"));
225
}
226
}
227
228
// Test success case
229
const onSuccess = sinon.fake();
230
const onError = sinon.fake();
231
232
processData({ valid: true, result: "test" }, onSuccess, onError);
233
234
console.log(onSuccess.calledOnce); // true
235
console.log(onSuccess.calledWith("test")); // true
236
console.log(onError.called); // false
237
238
// Test error case
239
const onSuccess2 = sinon.fake();
240
const onError2 = sinon.fake();
241
242
processData({ valid: false }, onSuccess2, onError2);
243
244
console.log(onSuccess2.called); // false
245
console.log(onError2.calledOnce); // true
246
console.log(onError2.firstCall.args[0].message); // "Invalid data"
247
```
248
249
### Async Testing with Fakes
250
251
Using fakes for Promise-based and async callback testing.
252
253
**Usage Examples:**
254
255
```javascript
256
// Promise-based fake
257
const apiCall = sinon.fake.resolves({ users: [] });
258
259
async function getUsers() {
260
return await apiCall("/users");
261
}
262
263
const users = await getUsers();
264
console.log(users); // { users: [] }
265
console.log(apiCall.calledWith("/users")); // true
266
267
// Async callback fake
268
const readFile = sinon.fake.yieldsAsync(null, "file contents");
269
270
function processFile(callback) {
271
readFile("test.txt", callback);
272
}
273
274
processFile((err, data) => {
275
console.log(data); // "file contents"
276
console.log(readFile.calledWith("test.txt")); // true
277
});
278
```
279
280
### Fake Lifecycle Management
281
282
Managing fake state and cleanup.
283
284
**Usage Examples:**
285
286
```javascript
287
const fake = sinon.fake();
288
289
fake("first call");
290
fake("second call");
291
292
console.log(fake.callCount); // 2
293
294
// Reset call history
295
fake.resetHistory();
296
console.log(fake.callCount); // 0
297
console.log(fake.called); // false
298
299
// Fakes on object methods can be restored
300
const obj = { method: sinon.fake.returns("test") };
301
// obj.method is now a fake
302
303
// If created via sandbox or sinon.replace, restore is available
304
const sandbox = sinon.createSandbox();
305
sandbox.replace(obj, "method", sinon.fake.returns("mocked"));
306
sandbox.restore(); // Restores original method
307
```
308
309
## Types
310
311
```javascript { .api }
312
// Fake extends all spy functionality
313
interface SinonFake extends SinonSpy {
314
// Inherits all SinonSpy properties and methods
315
// No additional methods beyond spy interface
316
}
317
318
// Generic fake interface for typed functions
319
interface SinonFake<F extends Function = Function> extends SinonFake {
320
(...args: Parameters<F>): ReturnType<F>;
321
}
322
323
// Static creation methods namespace
324
declare namespace fake {
325
function returns(value: any): SinonFake;
326
function throws(error?: any): SinonFake;
327
function resolves(value?: any): SinonFake;
328
function rejects(error?: any): SinonFake;
329
function yields(...args: any[]): SinonFake;
330
function yieldsAsync(...args: any[]): SinonFake;
331
}
332
```