or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

custom-extensions.mdenvironment-config.mdexpectations-matchers.mdindex.mdspy-system.mdtest-organization.mdtest-utilities.md
tile.json

spy-system.mddocs/

0

# Spy System

1

2

Jasmine's comprehensive mocking and spying functionality for testing object interactions, method calls, and return values. Includes spy creation, behavior configuration, call tracking, and verification.

3

4

## Capabilities

5

6

### Spy Creation Functions

7

8

Functions for creating spies on existing objects and methods.

9

10

```javascript { .api }

11

/**

12

* Install a spy on an existing object method

13

* @param obj - Object containing the method to spy on

14

* @param methodName - Name of the method to spy on

15

* @returns Spy object for configuration and verification

16

*/

17

function spyOn(obj: object, methodName: string): Spy;

18

19

/**

20

* Install a spy on an object property getter or setter

21

* @param obj - Object containing the property to spy on

22

* @param propertyName - Name of the property to spy on

23

* @param accessType - Type of access to spy on ('get', 'set', or both)

24

* @returns PropertySpy object

25

*/

26

function spyOnProperty(obj: object, propertyName: string, accessType?: 'get' | 'set'): PropertySpy;

27

28

/**

29

* Install spies on all functions of an object

30

* @param obj - Object to spy on all functions

31

* @param includeNonEnumerable - Whether to include non-enumerable functions

32

* @returns Object with all function names as keys and spies as values

33

*/

34

function spyOnAllFunctions(obj: object, includeNonEnumerable?: boolean): { [key: string]: Spy };

35

```

36

37

**Usage Examples:**

38

39

```javascript

40

const calculator = {

41

add: (a, b) => a + b,

42

multiply: (a, b) => a * b

43

};

44

45

// Spy on existing method

46

const addSpy = spyOn(calculator, 'add');

47

calculator.add(2, 3);

48

expect(addSpy).toHaveBeenCalledWith(2, 3);

49

50

// Spy on property

51

const obj = {

52

get value() { return this._value; },

53

set value(val) { this._value = val; }

54

};

55

56

spyOnProperty(obj, 'value', 'get');

57

const val = obj.value;

58

expect(obj.value).toHaveBeenCalled();

59

60

// Spy on all functions

61

const mathUtils = {

62

add: (a, b) => a + b,

63

subtract: (a, b) => a - b,

64

helper: () => 'helper'

65

};

66

67

spyOnAllFunctions(mathUtils);

68

mathUtils.add(1, 2);

69

mathUtils.subtract(5, 3);

70

expect(mathUtils.add).toHaveBeenCalled();

71

expect(mathUtils.subtract).toHaveBeenCalled();

72

```

73

74

### Jasmine Spy Factory Functions

75

76

Functions for creating standalone spies and spy objects.

77

78

```javascript { .api }

79

/**

80

* Create a standalone spy function

81

* @param name - Optional name for the spy (for better error messages)

82

* @param originalFn - Optional original function to wrap

83

* @returns Spy function

84

*/

85

jasmine.createSpy(name?: string, originalFn?: Function): Spy;

86

87

/**

88

* Create an object with multiple spy methods

89

* @param baseName - Base name for the spy object

90

* @param methodNames - Array of method names or object with method configurations

91

* @param propertyNames - Optional array of property names or object with property configurations

92

* @returns Object with spy methods and properties

93

*/

94

jasmine.createSpyObj(

95

baseName: string,

96

methodNames: string[] | { [methodName: string]: any },

97

propertyNames?: string[] | { [propertyName: string]: any }

98

): any;

99

```

100

101

**Usage Examples:**

102

103

```javascript

104

// Create standalone spy

105

const callback = jasmine.createSpy('callback');

106

callback('arg1', 'arg2');

107

expect(callback).toHaveBeenCalledWith('arg1', 'arg2');

108

109

// Create spy with original function

110

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

111

const spy = jasmine.createSpy('doubler', originalFn);

112

113

// Create spy object with methods

114

const userService = jasmine.createSpyObj('UserService', [

115

'getUser',

116

'saveUser',

117

'deleteUser'

118

]);

119

120

userService.getUser.and.returnValue({ id: 1, name: 'John' });

121

const user = userService.getUser(1);

122

expect(user.name).toBe('John');

123

124

// Create spy object with methods and properties

125

const apiClient = jasmine.createSpyObj(

126

'ApiClient',

127

['get', 'post'],

128

['baseUrl', 'timeout']

129

);

130

131

apiClient.baseUrl = 'https://api.example.com';

132

apiClient.get.and.returnValue(Promise.resolve({ data: 'response' }));

133

```

134

135

### Spy Behavior Configuration

136

137

Methods for configuring how spies behave when called.

138

139

```javascript { .api }

140

interface SpyStrategy {

141

/**

142

* Make spy return a specific value

143

* @param value - Value to return when spy is called

144

* @returns The spy for chaining

145

*/

146

returnValue(value: any): Spy;

147

148

/**

149

* Make spy return different values on successive calls

150

* @param ...values - Values to return in order

151

* @returns The spy for chaining

152

*/

153

returnValues(...values: any[]): Spy;

154

155

/**

156

* Make spy call a fake function instead of original

157

* @param fn - Function to call instead

158

* @returns The spy for chaining

159

*/

160

callFake(fn: Function): Spy;

161

162

/**

163

* Make spy call through to the original function

164

* @returns The spy for chaining

165

*/

166

callThrough(): Spy;

167

168

/**

169

* Make spy throw an error when called

170

* @param msg - Error message or Error object to throw

171

* @returns The spy for chaining

172

*/

173

throwError(msg?: string | Error): Spy;

174

175

/**

176

* Make spy do nothing when called (default behavior)

177

* @returns The spy for chaining

178

*/

179

stub(): Spy;

180

181

/**

182

* Make spy return a resolved promise

183

* @param value - Value to resolve with

184

* @returns The spy for chaining

185

*/

186

resolveTo(value?: any): Spy;

187

188

/**

189

* Make spy return a rejected promise

190

* @param value - Value to reject with

191

* @returns The spy for chaining

192

*/

193

rejectWith(value?: any): Spy;

194

}

195

```

196

197

**Usage Examples:**

198

199

```javascript

200

const spy = jasmine.createSpy('testSpy');

201

202

// Return specific value

203

spy.and.returnValue(42);

204

expect(spy()).toBe(42);

205

206

// Return different values

207

spy.and.returnValues(1, 2, 3);

208

expect(spy()).toBe(1);

209

expect(spy()).toBe(2);

210

expect(spy()).toBe(3);

211

212

// Call fake function

213

spy.and.callFake((x, y) => x + y);

214

expect(spy(5, 3)).toBe(8);

215

216

// Throw error

217

spy.and.throwError('Something went wrong');

218

expect(() => spy()).toThrowError('Something went wrong');

219

220

// Return promises

221

const asyncSpy = jasmine.createSpy('asyncSpy');

222

asyncSpy.and.resolveTo('success');

223

await expectAsync(asyncSpy()).toBeResolvedTo('success');

224

225

asyncSpy.and.rejectWith('error');

226

await expectAsync(asyncSpy()).toBeRejectedWith('error');

227

228

// Call through to original

229

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

230

spyOn(obj, 'method').and.callThrough();

231

expect(obj.method(5)).toBe(10); // calls original

232

expect(obj.method).toHaveBeenCalledWith(5);

233

```

234

235

### Call Tracking and Verification

236

237

Methods for tracking and verifying spy calls.

238

239

```javascript { .api }

240

interface CallTracker {

241

/**

242

* Get the number of times the spy was called

243

* @returns Number of calls

244

*/

245

count(): number;

246

247

/**

248

* Get arguments for a specific call

249

* @param index - Index of the call (0-based)

250

* @returns Array of arguments for that call

251

*/

252

argsFor(index: number): any[];

253

254

/**

255

* Get all arguments for all calls

256

* @returns Array of argument arrays

257

*/

258

allArgs(): any[][];

259

260

/**

261

* Get all call objects with full details

262

* @returns Array of call objects

263

*/

264

all(): CallInfo[];

265

266

/**

267

* Get the most recent call object

268

* @returns Most recent call object or undefined

269

*/

270

mostRecent(): CallInfo | undefined;

271

272

/**

273

* Get the first call object

274

* @returns First call object or undefined

275

*/

276

first(): CallInfo | undefined;

277

278

/**

279

* Reset the spy's call history

280

*/

281

reset(): void;

282

}

283

284

interface CallInfo {

285

object: any;

286

args: any[];

287

returnValue: any;

288

}

289

```

290

291

**Usage Examples:**

292

293

```javascript

294

const spy = jasmine.createSpy('testSpy');

295

296

spy('first', 'call');

297

spy('second', 'call');

298

spy('third', 'call');

299

300

// Check call count

301

expect(spy.calls.count()).toBe(3);

302

303

// Check specific call arguments

304

expect(spy.calls.argsFor(0)).toEqual(['first', 'call']);

305

expect(spy.calls.argsFor(1)).toEqual(['second', 'call']);

306

307

// Get all arguments

308

expect(spy.calls.allArgs()).toEqual([

309

['first', 'call'],

310

['second', 'call'],

311

['third', 'call']

312

]);

313

314

// Get call details

315

const firstCall = spy.calls.first();

316

expect(firstCall.args).toEqual(['first', 'call']);

317

318

const lastCall = spy.calls.mostRecent();

319

expect(lastCall.args).toEqual(['third', 'call']);

320

321

// Reset call history

322

spy.calls.reset();

323

expect(spy.calls.count()).toBe(0);

324

```

325

326

### Spy Object Interface

327

328

The complete spy object interface showing all available properties and methods.

329

330

```javascript { .api }

331

interface Spy extends Function {

332

/** Strategy object for configuring spy behavior */

333

and: SpyStrategy;

334

335

/** Call tracker for verifying calls */

336

calls: CallTracker;

337

338

/** Original function identity (internal) */

339

identity: string;

340

}

341

342

interface PropertySpy {

343

/** Strategy object for configuring property spy behavior */

344

and: SpyStrategy;

345

346

/** Call tracker for verifying property access */

347

calls: CallTracker;

348

}

349

```

350

351

### Advanced Spy Features

352

353

Additional spy functionality for complex testing scenarios.

354

355

```javascript { .api }

356

/**

357

* Add a custom spy strategy that can be used by any spy

358

* @param name - Name of the strategy

359

* @param factory - Function that creates the strategy

360

*/

361

jasmine.addSpyStrategy(name: string, factory: (spy: Spy) => Function): void;

362

363

/**

364

* Set the default spy strategy for all new spies

365

* @param defaultStrategyFn - Function that returns default strategy

366

*/

367

jasmine.setDefaultSpyStrategy(defaultStrategyFn: (name: string, originalFn?: Function) => Function): void;

368

```

369

370

**Usage Examples:**

371

372

```javascript

373

// Add custom spy strategy

374

jasmine.addSpyStrategy('returnRandomValue', (spy) => {

375

return () => Math.random();

376

});

377

378

const spy = jasmine.createSpy('randomSpy');

379

spy.and.returnRandomValue();

380

const result = spy();

381

expect(typeof result).toBe('number');

382

383

// Set default spy strategy

384

jasmine.setDefaultSpyStrategy((name, originalFn) => {

385

return function() {

386

console.log(`Spy ${name} was called`);

387

return originalFn ? originalFn.apply(this, arguments) : undefined;

388

};

389

});

390

```

391

392

### Spy Restoration

393

394

Methods for restoring original functionality after spying.

395

396

```javascript { .api }

397

/**

398

* Restore all spies to their original functions

399

* Usually called in afterEach hooks

400

*/

401

function restoreAllSpies(): void;

402

```

403

404

**Usage Examples:**

405

406

```javascript

407

describe('Test suite with spies', () => {

408

let originalConsoleLog;

409

410

beforeEach(() => {

411

originalConsoleLog = console.log;

412

spyOn(console, 'log');

413

});

414

415

afterEach(() => {

416

// Restore all spies after each test

417

restoreAllSpies();

418

});

419

420

it('should spy on console.log', () => {

421

console.log('test message');

422

expect(console.log).toHaveBeenCalledWith('test message');

423

});

424

425

it('should have clean slate', () => {

426

// console.log spy is restored to original

427

expect(console.log).toBe(originalConsoleLog);

428

});

429

});

430

```

431

432

## Types

433

434

```javascript { .api }

435

interface Spy extends Function {

436

and: SpyStrategy;

437

calls: CallTracker;

438

identity: string;

439

}

440

441

interface SpyStrategy {

442

returnValue(value: any): Spy;

443

returnValues(...values: any[]): Spy;

444

callFake(fn: Function): Spy;

445

callThrough(): Spy;

446

throwError(msg?: string | Error): Spy;

447

stub(): Spy;

448

resolveTo(value?: any): Spy;

449

rejectWith(value?: any): Spy;

450

}

451

452

interface CallTracker {

453

count(): number;

454

argsFor(index: number): any[];

455

allArgs(): any[][];

456

all(): CallInfo[];

457

mostRecent(): CallInfo | undefined;

458

first(): CallInfo | undefined;

459

reset(): void;

460

}

461

462

interface CallInfo {

463

object: any;

464

args: any[];

465

returnValue: any;

466

}

467

468

interface PropertySpy {

469

and: SpyStrategy;

470

calls: CallTracker;

471

}

472

```