or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdindex.mdmock-builder.mdmock-creation.mdmock-instance.mdmock-render.mdtesting-utilities.md

mock-instance.mddocs/

0

# Runtime Mock Customization

1

2

Runtime mock instance customization with MockInstance for modifying behavior during test execution. Supports method stubbing, property overrides, and lifecycle management for fine-grained control over mock behavior.

3

4

## Capabilities

5

6

### MockInstance Function

7

8

Customizes mock instances at runtime with support for methods, properties, getters, and setters.

9

10

```typescript { .api }

11

/**

12

* Customizes a getter property on a mock class

13

* @param instance - Mock class to customize

14

* @param name - Property name to customize

15

* @param stub - Getter function implementation

16

* @param encapsulation - Must be 'get' for getter

17

* @returns The stub function

18

*/

19

function MockInstance<T extends object, K extends keyof T, S extends () => T[K]>(

20

instance: AnyType<T>,

21

name: K,

22

stub: S,

23

encapsulation: 'get'

24

): S;

25

26

/**

27

* Customizes a setter property on a mock class

28

* @param instance - Mock class to customize

29

* @param name - Property name to customize

30

* @param stub - Setter function implementation

31

* @param encapsulation - Must be 'set' for setter

32

* @returns The stub function

33

*/

34

function MockInstance<T extends object, K extends keyof T, S extends (value: T[K]) => void>(

35

instance: AnyType<T>,

36

name: K,

37

stub: S,

38

encapsulation: 'set'

39

): S;

40

41

/**

42

* Customizes a method or property on a mock class

43

* @param instance - Mock class to customize

44

* @param name - Method/property name to customize

45

* @param stub - Implementation function or value

46

* @returns The stub function or value

47

*/

48

function MockInstance<T extends object, K extends keyof T, S extends T[K]>(

49

instance: AnyType<T>,

50

name: K,

51

stub: S

52

): S;

53

54

/**

55

* Applies multiple customizations to a mock class

56

* @param instance - Mock class to customize

57

* @param overrides - Object with property overrides

58

* @returns The overrides object

59

*/

60

function MockInstance<T extends object>(

61

instance: AnyType<T>,

62

overrides: Partial<T>

63

): typeof overrides;

64

65

/**

66

* Sets up automatic initialization for mock instances

67

* @param instance - Mock class to customize

68

* @param init - Initialization function called when instance is created

69

* @returns The initialization function

70

*/

71

function MockInstance<T extends object>(

72

instance: AnyType<T>,

73

init?: (instance: T, injector: Injector) => Partial<T>

74

): typeof init;

75

```

76

77

**Usage Examples:**

78

79

```typescript

80

import { MockInstance } from "ng-mocks";

81

82

// Customize a method

83

MockInstance(AuthService, 'login', jasmine.createSpy('login')

84

.and.returnValue(of({ success: true })));

85

86

// Customize a property getter

87

MockInstance(ConfigService, 'apiUrl', () => 'http://test-api.com', 'get');

88

89

// Customize a property setter

90

MockInstance(UserService, 'currentUser', (user) => {

91

console.log('Setting user:', user);

92

}, 'set');

93

94

// Apply multiple customizations

95

MockInstance(DataService, {

96

getData: jasmine.createSpy('getData').and.returnValue(of([])),

97

isLoading: false,

98

errorMessage: null

99

});

100

101

// Automatic initialization

102

MockInstance(AuthService, (instance, injector) => ({

103

isAuthenticated: true,

104

user: { id: 1, name: 'Test User' },

105

login: jasmine.createSpy('login').and.returnValue(of({ success: true }))

106

}));

107

```

108

109

### MockReset Function

110

111

Resets MockInstance customizations for specified classes.

112

113

```typescript { .api }

114

/**

115

* Resets MockInstance customizations for one or more classes

116

* @param instances - Classes to reset MockInstance customizations for

117

*/

118

function MockReset(...instances: Array<AnyType<any>>): void;

119

```

120

121

**Usage Examples:**

122

123

```typescript

124

import { MockInstance, MockReset } from "ng-mocks";

125

126

// Set up customizations

127

MockInstance(AuthService, 'isAuthenticated', true);

128

MockInstance(DataService, 'getData', () => of(mockData));

129

130

// Reset specific services

131

MockReset(AuthService, DataService);

132

133

// In test cleanup

134

afterEach(() => {

135

MockReset(AuthService, DataService, ConfigService);

136

});

137

```

138

139

### Runtime Customization Patterns

140

141

Common patterns for using MockInstance effectively in tests.

142

143

**Service Method Stubbing:**

144

145

```typescript

146

import { MockInstance, MockReset } from "ng-mocks";

147

148

describe('UserComponent', () => {

149

beforeEach(() => {

150

// Customize service behavior for all tests

151

MockInstance(UserService, 'getUsers', jasmine.createSpy('getUsers')

152

.and.returnValue(of([

153

{ id: 1, name: 'John' },

154

{ id: 2, name: 'Jane' }

155

])));

156

157

MockInstance(AuthService, 'isAuthenticated', true);

158

});

159

160

afterEach(() => {

161

// Clean up customizations

162

MockReset(UserService, AuthService);

163

});

164

165

it('should load users on init', () => {

166

const fixture = MockRender(UserComponent);

167

const userService = ngMocks.get(UserService);

168

169

expect(userService.getUsers).toHaveBeenCalled();

170

});

171

});

172

```

173

174

**Property Access Control:**

175

176

```typescript

177

// Control property access

178

MockInstance(ConfigService, 'environment', () => 'test', 'get');

179

MockInstance(ConfigService, 'debug', (value) => {

180

console.log('Debug mode set to:', value);

181

}, 'set');

182

183

// Use in test

184

const config = ngMocks.get(ConfigService);

185

expect(config.environment).toBe('test');

186

config.debug = true; // Logs: "Debug mode set to: true"

187

```

188

189

**Dynamic Behavior Based on Test Context:**

190

191

```typescript

192

describe('Component with different service states', () => {

193

beforeEach(() => {

194

MockInstance(DataService, (instance) => {

195

// Different behavior based on test context

196

if (jasmine.currentSpec.description.includes('loading')) {

197

return { isLoading: true, data: null };

198

} else if (jasmine.currentSpec.description.includes('error')) {

199

return {

200

isLoading: false,

201

data: null,

202

error: 'Network error'

203

};

204

} else {

205

return {

206

isLoading: false,

207

data: [{ id: 1, name: 'Test' }],

208

error: null

209

};

210

}

211

});

212

});

213

214

it('should show loading state', () => {

215

const fixture = MockRender(MyComponent);

216

const service = ngMocks.get(DataService);

217

expect(service.isLoading).toBe(true);

218

});

219

220

it('should show error state', () => {

221

const fixture = MockRender(MyComponent);

222

const service = ngMocks.get(DataService);

223

expect(service.error).toBe('Network error');

224

});

225

});

226

```

227

228

**Chained Method Calls:**

229

230

```typescript

231

// Mock fluent interface

232

MockInstance(QueryBuilder, 'where', function(this: any, condition: string) {

233

this.conditions = this.conditions || [];

234

this.conditions.push(condition);

235

return this;

236

});

237

238

MockInstance(QueryBuilder, 'orderBy', function(this: any, field: string) {

239

this.orderField = field;

240

return this;

241

});

242

243

MockInstance(QueryBuilder, 'execute', function(this: any) {

244

return of({

245

conditions: this.conditions,

246

orderField: this.orderField

247

});

248

});

249

250

// Use in test

251

const queryBuilder = ngMocks.get(QueryBuilder);

252

const result = queryBuilder

253

.where('active = true')

254

.where('role = "admin"')

255

.orderBy('name')

256

.execute();

257

```

258

259

**Lifecycle Management:**

260

261

```typescript

262

describe('Component lifecycle', () => {

263

let serviceSpies: { [key: string]: jasmine.Spy };

264

265

beforeEach(() => {

266

serviceSpies = {

267

init: jasmine.createSpy('init'),

268

destroy: jasmine.createSpy('destroy'),

269

load: jasmine.createSpy('load').and.returnValue(of({}))

270

};

271

272

MockInstance(LifecycleService, serviceSpies);

273

});

274

275

afterEach(() => {

276

MockReset(LifecycleService);

277

});

278

279

it('should call init on component creation', () => {

280

const fixture = MockRender(MyComponent);

281

expect(serviceSpies.init).toHaveBeenCalled();

282

});

283

284

it('should call destroy on component destruction', () => {

285

const fixture = MockRender(MyComponent);

286

fixture.destroy();

287

expect(serviceSpies.destroy).toHaveBeenCalled();

288

});

289

});

290

```

291

292

**Integration with MockBuilder:**

293

294

```typescript

295

// Combine MockInstance with MockBuilder

296

describe('Integration test', () => {

297

beforeEach(() => {

298

// Set up MockInstance customizations

299

MockInstance(AuthService, 'user', { id: 1, role: 'admin' });

300

MockInstance(ConfigService, 'features', ['feature1', 'feature2']);

301

302

// Configure test environment

303

return MockBuilder(MyComponent, MyModule)

304

.keep(AuthService) // Keep real AuthService, but with MockInstance customizations

305

.mock(HttpClient)

306

.build();

307

});

308

309

afterEach(() => {

310

MockReset(AuthService, ConfigService);

311

});

312

313

it('should work with customized services', () => {

314

const fixture = MockRender(MyComponent);

315

const auth = ngMocks.get(AuthService);

316

317

expect(auth.user.role).toBe('admin');

318

});

319

});

320

```

321

322

### Advanced Customization Techniques

323

324

**Conditional Stubbing:**

325

326

```typescript

327

MockInstance(ApiService, 'request', (url: string) => {

328

if (url.includes('/users')) {

329

return of({ users: [{ id: 1, name: 'Test' }] });

330

} else if (url.includes('/error')) {

331

return throwError({ status: 500, message: 'Server Error' });

332

} else {

333

return of({ data: 'default' });

334

}

335

});

336

```

337

338

**State-Dependent Behavior:**

339

340

```typescript

341

let serviceState = { authenticated: false, user: null };

342

343

MockInstance(AuthService, 'isAuthenticated', () => serviceState.authenticated, 'get');

344

MockInstance(AuthService, 'user', () => serviceState.user, 'get');

345

MockInstance(AuthService, 'login', (credentials: any) => {

346

serviceState.authenticated = true;

347

serviceState.user = { id: 1, name: 'Test User' };

348

return of({ success: true });

349

});

350

MockInstance(AuthService, 'logout', () => {

351

serviceState.authenticated = false;

352

serviceState.user = null;

353

return of({ success: true });

354

});

355

```

356

357

**Spy Integration:**

358

359

```typescript

360

// Create comprehensive spy setup

361

const createServiceSpy = (methodName: string) => {

362

return jasmine.createSpy(methodName).and.callThrough();

363

};

364

365

MockInstance(DataService, {

366

load: createServiceSpy('load').and.returnValue(of([])),

367

save: createServiceSpy('save').and.returnValue(of({ success: true })),

368

delete: createServiceSpy('delete').and.returnValue(of({ success: true }))

369

});

370

```