0
# Sandbox Management
1
2
Sinon's sandbox provides an isolated testing environment that manages all fakes (spies, stubs, mocks) and ensures proper cleanup between tests. Sandboxes prevent test interference and memory leaks by automatically tracking and restoring all created fakes.
3
4
## Capabilities
5
6
### Creating Sandboxes
7
8
Creates a new isolated sandbox for managing test fakes.
9
10
```javascript { .api }
11
/**
12
* Creates a new sandbox instance for isolated testing
13
* @param options - Configuration options for the sandbox
14
* @returns A new sandbox instance
15
*/
16
function createSandbox(options?: SandboxOptions): SinonSandbox;
17
18
interface SandboxOptions {
19
/** Object to inject sandbox methods into */
20
injectInto?: object;
21
/** Properties to inject when using injectInto */
22
properties?: string[];
23
/** Automatically install fake timers */
24
useFakeTimers?: boolean | FakeTimerConfig;
25
/** Automatically install fake server (XMLHttpRequest) */
26
useFakeServer?: boolean;
27
}
28
```
29
30
**Usage Examples:**
31
32
```javascript
33
import { createSandbox } from "sinon";
34
35
// Basic sandbox
36
const sandbox = createSandbox();
37
38
// Sandbox with fake timers
39
const sandbox = createSandbox({
40
useFakeTimers: true
41
});
42
43
// Inject methods into test context
44
const testContext = {};
45
const sandbox = createSandbox({
46
injectInto: testContext,
47
properties: ["spy", "stub", "mock"]
48
});
49
// Now testContext.spy, testContext.stub, etc. are available
50
```
51
52
### Sandbox Instance Methods
53
54
Core methods available on sandbox instances for creating and managing fakes.
55
56
```javascript { .api }
57
interface SinonSandbox {
58
/** Create an anonymous spy */
59
spy(): SinonSpy;
60
/** Wrap a function with a spy */
61
spy<F extends Function>(func: F): SinonSpy<F>;
62
/** Replace object method with spy */
63
spy<T>(object: T, method: keyof T): SinonSpy;
64
65
/** Create an anonymous stub */
66
stub(): SinonStub;
67
/** Replace object method with stub */
68
stub<T>(object: T, method: keyof T): SinonStub;
69
/** Replace object method with custom stub implementation */
70
stub<T>(object: T, method: keyof T, func: Function): SinonStub;
71
72
/** Create a mock for an object */
73
mock(object: any): SinonMock;
74
75
/** Create a fake function */
76
fake(func?: Function): SinonFake;
77
78
/** Replace object property with a value */
79
replace<T>(object: T, property: keyof T, replacement: any): void & {
80
/** Replace object property using accessor-based assignment */
81
usingAccessor<T>(object: T, property: keyof T, replacement: any): void;
82
};
83
/** Replace object getter */
84
replaceGetter<T>(object: T, property: keyof T, getter: () => any): void;
85
/** Replace object setter */
86
replaceSetter<T>(object: T, property: keyof T, setter: (value: any) => void): void;
87
88
/** Install fake timers */
89
useFakeTimers(config?: FakeTimerConfig): SinonClock;
90
91
/** Access to fake timers clock after installation */
92
clock?: SinonClock;
93
94
/** Access to assertion methods */
95
assert: SinonAssert;
96
97
/** Access to matcher utilities */
98
match: SinonMatch;
99
}
100
```
101
102
### Property Replacement
103
104
Replace object properties, getters, and setters with controlled values or functions for testing.
105
106
**Usage Examples:**
107
108
```javascript
109
import { createSandbox } from "sinon";
110
111
const sandbox = createSandbox();
112
113
const myObject = {
114
config: { apiUrl: "https://api.example.com" },
115
get status() { return "active"; },
116
set status(value) { this._status = value; }
117
};
118
119
// Replace property value
120
sandbox.replace(myObject, "config", { apiUrl: "https://test-api.example.com" });
121
console.log(myObject.config.apiUrl); // "https://test-api.example.com"
122
123
// Replace using accessor-based assignment (for properties with setters)
124
sandbox.replace.usingAccessor(myObject, "status", "testing");
125
console.log(myObject.status); // "testing"
126
127
// Replace getter
128
sandbox.replaceGetter(myObject, "status", () => "mocked-status");
129
console.log(myObject.status); // "mocked-status"
130
131
// Replace setter
132
sandbox.replaceSetter(myObject, "status", (value) => {
133
console.log("Setter called with:", value);
134
});
135
myObject.status = "new-value"; // Logs: "Setter called with: new-value"
136
137
// Cleanup restores all replacements
138
sandbox.restore();
139
```
140
141
### Sandbox Lifecycle Methods
142
143
Methods for managing the sandbox lifecycle and cleaning up created fakes.
144
145
```javascript { .api }
146
interface SinonSandbox {
147
/** Restore all fakes in the sandbox to their original state */
148
restore(): void;
149
150
/** Reset call history for all fakes */
151
resetHistory(): void;
152
153
/** Reset behavior for all stubs to their default */
154
resetBehavior(): void;
155
156
/** Reset both history and behavior for all fakes */
157
reset(): void;
158
159
/** Verify all mock expectations in the sandbox */
160
verify(): void;
161
162
/** Verify all mocks and then restore */
163
verifyAndRestore(): void;
164
165
/** Get array of all fakes created by this sandbox */
166
getFakes(): SinonSpy[];
167
}
168
```
169
170
**Usage Examples:**
171
172
```javascript
173
import { createSandbox } from "sinon";
174
175
describe("User service", () => {
176
let sandbox;
177
178
beforeEach(() => {
179
sandbox = createSandbox();
180
});
181
182
afterEach(() => {
183
sandbox.restore(); // Clean up all fakes
184
});
185
186
it("should fetch user data", () => {
187
const fetchStub = sandbox.stub(api, "fetch").resolves({ id: 1 });
188
189
return userService.getUser(1).then(user => {
190
assert(fetchStub.calledOnce);
191
assert.equal(user.id, 1);
192
});
193
});
194
});
195
```
196
197
### Default Sandbox
198
199
The main sinon export is a pre-configured sandbox instance, providing all sandbox methods directly.
200
201
```javascript { .api }
202
// The main sinon object extends SinonSandbox
203
interface SinonStatic extends SinonSandbox {
204
/** Create a new sandbox (same as createSandbox) */
205
createSandbox(options?: SandboxOptions): SinonSandbox;
206
207
/** Restore all methods on an object to their original implementation */
208
restoreObject(object: any): void;
209
210
/** Global access to matchers */
211
match: SinonMatch;
212
213
/** Global access to assertions */
214
assert: SinonAssert;
215
}
216
```
217
218
**Usage Examples:**
219
220
```javascript
221
import sinon from "sinon";
222
223
// Using the default sandbox
224
const spy = sinon.spy();
225
const stub = sinon.stub(obj, "method");
226
227
// Restore everything on the default sandbox
228
sinon.restore();
229
230
// Or create isolated sandboxes
231
const sandbox1 = sinon.createSandbox();
232
const sandbox2 = sinon.createSandbox();
233
```
234
235
### Memory Management
236
237
Sandbox memory management and leak detection capabilities.
238
239
```javascript { .api }
240
interface SinonSandbox {
241
/** Threshold for detecting memory leaks (default: 10000) */
242
leakThreshold: number;
243
}
244
```
245
246
**Usage Examples:**
247
248
```javascript
249
const sandbox = createSandbox();
250
251
// Adjust leak detection threshold
252
sandbox.leakThreshold = 5000;
253
254
// In test cleanup, restore prevents memory leaks
255
afterEach(() => {
256
sandbox.restore();
257
});
258
```
259
260
## Types
261
262
```javascript { .api }
263
interface FakeTimerConfig {
264
/** Starting time for the fake clock */
265
now?: number | Date;
266
/** Array of timer methods to fake */
267
toFake?: ("setTimeout" | "clearTimeout" | "setInterval" | "clearInterval" | "Date")[];
268
/** Whether time should advance automatically */
269
shouldAdvanceTime?: boolean;
270
/** How much time should advance per tick */
271
advanceTimeDelta?: number;
272
}
273
```