or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdfakes.mdindex.mdmatchers.mdmocks.mdpromises.mdsandbox.mdspies.mdstubs.mdtimers.md

spies.mddocs/

0

# Test Spies

1

2

Test spies record function calls, arguments, return values, and exceptions without changing the original function's behavior. They're perfect for verifying that functions are called correctly and for observing interactions between components.

3

4

## Capabilities

5

6

### Creating Spies

7

8

Create spies to monitor function calls and gather interaction data.

9

10

```javascript { .api }

11

/**

12

* Creates an anonymous spy function

13

* @returns New spy function that records calls

14

*/

15

function spy(): SinonSpy;

16

17

/**

18

* Wraps an existing function with spy functionality

19

* @param func - Function to wrap with spy

20

* @returns Spy wrapping the original function

21

*/

22

function spy<F extends Function>(func: F): SinonSpy<F>;

23

24

/**

25

* Replaces an object method with a spy

26

* @param object - Object containing the method

27

* @param method - Method name to spy on

28

* @returns Spy replacing the original method

29

*/

30

function spy<T>(object: T, method: keyof T): SinonSpy;

31

```

32

33

**Usage Examples:**

34

35

```javascript

36

import { spy } from "sinon";

37

38

// Anonymous spy

39

const callback = spy();

40

someFunction(callback);

41

console.log(callback.called); // true

42

43

// Spy on existing function

44

const originalFn = (x) => x * 2;

45

const spiedFn = spy(originalFn);

46

console.log(spiedFn(5)); // 10 (original behavior preserved)

47

console.log(spiedFn.calledWith(5)); // true

48

49

// Spy on object method

50

const user = { getName: () => "John" };

51

const nameSpy = spy(user, "getName");

52

user.getName(); // Still returns "John"

53

console.log(nameSpy.calledOnce); // true

54

```

55

56

### Property Spying

57

58

Spy on object property getters and setters to monitor property access patterns.

59

60

```javascript { .api }

61

/**

62

* Spy on object property accessors (getter/setter)

63

* @param object - Object containing the property

64

* @param property - Property name to spy on

65

* @param accessors - Array specifying which accessors to spy on

66

* @returns Spy for the property accessors

67

*/

68

function spy<T>(object: T, property: keyof T, accessors: ["get"] | ["set"] | ["get", "set"]): SinonSpy;

69

```

70

71

**Usage Examples:**

72

73

```javascript

74

import { spy } from "sinon";

75

76

const user = {

77

_name: "John",

78

get name() {

79

return this._name;

80

},

81

set name(value) {

82

this._name = value;

83

}

84

};

85

86

// Spy on getter only

87

const getterSpy = spy(user, "name", ["get"]);

88

console.log(user.name); // "John"

89

console.log(getterSpy.calledOnce); // true

90

91

// Spy on setter only

92

const setterSpy = spy(user, "name", ["set"]);

93

user.name = "Jane";

94

console.log(setterSpy.calledOnce); // true

95

console.log(setterSpy.calledWith("Jane")); // true

96

97

// Spy on both getter and setter

98

const user2 = { /* similar object */ };

99

const accessorSpy = spy(user2, "name", ["get", "set"]);

100

user2.name = "Bob"; // Records setter call

101

console.log(user2.name); // Records getter call

102

console.log(accessorSpy.callCount); // 2

103

```

104

105

### Spy Properties

106

107

Properties for checking spy call state and history.

108

109

```javascript { .api }

110

interface SinonSpy {

111

/** Whether the spy was called at least once */

112

called: boolean;

113

114

/** Number of times the spy was called */

115

callCount: number;

116

117

/** Whether the spy was called exactly once */

118

calledOnce: boolean;

119

120

/** Whether the spy was called exactly twice */

121

calledTwice: boolean;

122

123

/** Whether the spy was called exactly three times */

124

calledThrice: boolean;

125

126

/** First call object (null if never called) */

127

firstCall: SinonSpyCall | null;

128

129

/** Second call object (null if called less than twice) */

130

secondCall: SinonSpyCall | null;

131

132

/** Third call object (null if called less than three times) */

133

thirdCall: SinonSpyCall | null;

134

135

/** Last call object (null if never called) */

136

lastCall: SinonSpyCall | null;

137

}

138

```

139

140

### Argument Verification

141

142

Methods for verifying spy calls with specific arguments.

143

144

```javascript { .api }

145

interface SinonSpy {

146

/**

147

* Check if spy was called with specific arguments (partial match)

148

* @param args - Arguments to check for

149

* @returns Whether spy was called with these arguments

150

*/

151

calledWith(...args: any[]): boolean;

152

153

/**

154

* Check if spy was called with exact arguments (exact match)

155

* @param args - Exact arguments to check for

156

* @returns Whether spy was called with exactly these arguments

157

*/

158

calledWithExactly(...args: any[]): boolean;

159

160

/**

161

* Check if spy was called with arguments matching patterns

162

* @param matchers - Matcher patterns to check against

163

* @returns Whether spy was called with matching arguments

164

*/

165

calledWithMatch(...matchers: any[]): boolean;

166

167

/**

168

* Check if spy was always called with specific arguments

169

* @param args - Arguments that should be present in every call

170

* @returns Whether every call included these arguments

171

*/

172

alwaysCalledWith(...args: any[]): boolean;

173

174

/**

175

* Check if spy was always called with exact arguments

176

* @param args - Exact arguments for every call

177

* @returns Whether every call had exactly these arguments

178

*/

179

alwaysCalledWithExactly(...args: any[]): boolean;

180

181

/**

182

* Check if spy was always called with matching arguments

183

* @param matchers - Matcher patterns for every call

184

* @returns Whether every call matched these patterns

185

*/

186

alwaysCalledWithMatch(...matchers: any[]): boolean;

187

188

/**

189

* Check if spy was never called with specific arguments

190

* @param args - Arguments that should never be present

191

* @returns Whether spy was never called with these arguments

192

*/

193

neverCalledWith(...args: any[]): boolean;

194

195

/**

196

* Check if spy was never called with matching arguments

197

* @param matchers - Matcher patterns that should never match

198

* @returns Whether spy was never called with matching arguments

199

*/

200

neverCalledWithMatch(...matchers: any[]): boolean;

201

}

202

```

203

204

**Usage Examples:**

205

206

```javascript

207

const spy = sinon.spy();

208

209

spy("hello", { name: "world" });

210

spy("goodbye", { name: "world" });

211

212

console.log(spy.calledWith("hello")); // true

213

console.log(spy.calledWithExactly("hello", { name: "world" })); // true

214

console.log(spy.alwaysCalledWith({ name: "world" })); // true

215

console.log(spy.neverCalledWith("invalid")); // true

216

217

// Using matchers

218

import { match } from "sinon";

219

console.log(spy.calledWithMatch("hello", match.object)); // true

220

```

221

222

### Context Verification

223

224

Methods for verifying the `this` context of spy calls.

225

226

```javascript { .api }

227

interface SinonSpy {

228

/**

229

* Check if spy was called with specific `this` context

230

* @param thisValue - The expected `this` value

231

* @returns Whether spy was called with this context

232

*/

233

calledOn(thisValue: any): boolean;

234

235

/**

236

* Check if spy was always called with specific `this` context

237

* @param thisValue - The expected `this` value for all calls

238

* @returns Whether all calls used this context

239

*/

240

alwaysCalledOn(thisValue: any): boolean;

241

242

/**

243

* Check if spy was called as a constructor (with `new`)

244

* @returns Whether spy was called with `new` operator

245

*/

246

calledWithNew(): boolean;

247

248

/**

249

* Check if spy was always called as a constructor

250

* @returns Whether all calls used `new` operator

251

*/

252

alwaysCalledWithNew(): boolean;

253

}

254

```

255

256

### Return Value Verification

257

258

Methods for verifying spy return values and exceptions.

259

260

```javascript { .api }

261

interface SinonSpy {

262

/**

263

* Check if spy threw an exception

264

* @param error - Optional specific error to check for

265

* @returns Whether spy threw (the specified) exception

266

*/

267

threw(error?: any): boolean;

268

269

/**

270

* Check if spy always threw an exception

271

* @param error - Optional specific error to check for

272

* @returns Whether spy always threw (the specified) exception

273

*/

274

alwaysThrew(error?: any): boolean;

275

276

/**

277

* Check if spy returned a specific value

278

* @param value - The expected return value

279

* @returns Whether spy returned this value

280

*/

281

returned(value: any): boolean;

282

283

/**

284

* Check if spy always returned a specific value

285

* @param value - The expected return value for all calls

286

* @returns Whether spy always returned this value

287

*/

288

alwaysReturned(value: any): boolean;

289

}

290

```

291

292

### Call Access

293

294

Methods for accessing individual calls and their details.

295

296

```javascript { .api }

297

interface SinonSpy {

298

/**

299

* Get a specific call by index

300

* @param index - Zero-based call index

301

* @returns Call object or null if index is invalid

302

*/

303

getCall(index: number): SinonSpyCall | null;

304

305

/**

306

* Get all calls made to the spy

307

* @returns Array of all call objects

308

*/

309

getCalls(): SinonSpyCall[];

310

311

/**

312

* Create spy subset that only considers calls with specific arguments

313

* @param args - Arguments to filter calls by

314

* @returns New spy containing only matching calls

315

*/

316

withArgs(...args: any[]): SinonSpy;

317

}

318

```

319

320

### Spy Utilities

321

322

Utility methods for managing spy state and formatting.

323

324

```javascript { .api }

325

interface SinonSpy {

326

/**

327

* Reset the spy's call history (but keep the spy active)

328

*/

329

resetHistory(): void;

330

331

/**

332

* Restore the original method (for spies on object methods)

333

*/

334

restore(): void;

335

336

/**

337

* Format spy information with custom format string

338

* @param format - Format string with placeholders like %n, %c, etc.

339

* @param args - Additional arguments for formatting

340

* @returns Formatted string representation

341

*/

342

printf(format: string, ...args: any[]): string;

343

}

344

```

345

346

**Usage Examples:**

347

348

```javascript

349

const obj = { method: (x) => x * 2 };

350

const spy = sinon.spy(obj, "method");

351

352

obj.method(5);

353

obj.method(10);

354

355

// Access specific calls

356

console.log(spy.getCall(0).args); // [5]

357

console.log(spy.getCall(1).args); // [10]

358

359

// Get all calls

360

const calls = spy.getCalls();

361

console.log(calls.length); // 2

362

363

// Create filtered spy

364

const spy5 = spy.withArgs(5);

365

console.log(spy5.calledOnce); // true

366

367

// Cleanup

368

spy.resetHistory();

369

console.log(spy.callCount); // 0

370

spy.restore(); // Restore original method

371

```

372

373

## Types

374

375

```javascript { .api }

376

interface SinonSpyCall {

377

/** Arguments passed to this call */

378

args: any[];

379

380

/** The `this` value for this call */

381

thisValue: any;

382

383

/** Return value of this call */

384

returnValue: any;

385

386

/** Exception thrown by this call (if any) */

387

exception: Error | null;

388

389

/** Check if this call was made with specific arguments */

390

calledWith(...args: any[]): boolean;

391

392

/** Check if this call was made with exact arguments */

393

calledWithExactly(...args: any[]): boolean;

394

395

/** Check if this call was made with matching arguments */

396

calledWithMatch(...matchers: any[]): boolean;

397

398

/** Check if this call was made with specific `this` context */

399

calledOn(thisValue: any): boolean;

400

401

/** Check if this call returned a specific value */

402

returned(value: any): boolean;

403

404

/** Check if this call threw an exception */

405

threw(error?: any): boolean;

406

}

407

408

// Generic spy interface for typed functions

409

interface SinonSpy<F extends Function = Function> extends SinonSpy {

410

(...args: Parameters<F>): ReturnType<F>;

411

}

412

```