or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-testing.mdindex.mdmock-integration.mdmodule-building.mdmodule-overriding.mdprovider-overriding.md

mock-integration.mddocs/

0

# Mock Integration

1

2

Global mocking system with automatic fallback for unresolved dependencies. This system integrates with popular mocking libraries to provide comprehensive test isolation and automatic mock generation for missing dependencies.

3

4

## Capabilities

5

6

### Mock Factory Integration

7

8

The TestingModuleBuilder supports global mock factories that automatically create mocks for unresolved dependencies.

9

10

```typescript { .api }

11

class TestingModuleBuilder {

12

/**

13

* Set a global mock factory for automatic dependency mocking

14

* @param mocker - Function that creates mocks based on injection tokens

15

* @returns TestingModuleBuilder for method chaining

16

*/

17

useMocker(mocker: MockFactory): TestingModuleBuilder;

18

}

19

20

/**

21

* Function type for creating mocks based on injection tokens

22

* @param token - The injection token for the dependency that needs mocking

23

* @returns Mock implementation for the dependency

24

*/

25

type MockFactory = (token?: InjectionToken) => any;

26

```

27

28

### Automatic Mock Resolution

29

30

The testing system automatically creates mocks for missing dependencies when a MockFactory is provided. When the dependency injection system cannot resolve a dependency, it falls back to using the mock factory to create a replacement.

31

32

**Usage Examples:**

33

34

```typescript

35

import { Test, TestingModule } from "@nestjs/testing";

36

import { createMock } from "@golevelup/ts-jest";

37

import { UsersService } from "./users.service";

38

import { DatabaseService } from "./database.service";

39

import { EmailService } from "./email.service";

40

41

describe("Mock Integration", () => {

42

let module: TestingModule;

43

44

beforeEach(async () => {

45

// Using @golevelup/ts-jest for automatic mocking

46

module = await Test.createTestingModule({

47

providers: [UsersService],

48

// Note: DatabaseService and EmailService are not provided

49

})

50

.useMocker(createMock)

51

.compile();

52

});

53

54

it("should automatically mock missing dependencies", async () => {

55

const usersService = module.get<UsersService>(UsersService);

56

57

// DatabaseService is automatically mocked

58

const result = await usersService.getUsers();

59

expect(result).toBeDefined();

60

});

61

});

62

```

63

64

### Custom Mock Factory

65

66

Create custom mock factories for specific testing needs:

67

68

```typescript

69

// Simple mock factory

70

const simpleMockFactory = (token: any): any => {

71

if (typeof token === "function") {

72

// For class constructors, create an object with mocked methods

73

const mockObj = {};

74

const prototype = token.prototype;

75

76

if (prototype) {

77

Object.getOwnPropertyNames(prototype).forEach((method) => {

78

if (method !== "constructor" && typeof prototype[method] === "function") {

79

mockObj[method] = jest.fn();

80

}

81

});

82

}

83

return mockObj;

84

}

85

86

// For tokens/strings, return a simple mock

87

return jest.fn();

88

};

89

90

// Advanced mock factory with type-aware mocking

91

const advancedMockFactory = (token: any): any => {

92

const tokenName = token?.name || token?.toString();

93

94

switch (tokenName) {

95

case "DatabaseService":

96

return {

97

findUser: jest.fn().mockResolvedValue({ id: 1, name: "Mock User" }),

98

saveUser: jest.fn().mockResolvedValue({ id: 1 }),

99

deleteUser: jest.fn().mockResolvedValue(true),

100

};

101

102

case "EmailService":

103

return {

104

sendEmail: jest.fn().mockResolvedValue({ sent: true, id: "mock-id" }),

105

validateEmail: jest.fn().mockReturnValue(true),

106

};

107

108

case "Logger":

109

return {

110

log: jest.fn(),

111

error: jest.fn(),

112

warn: jest.fn(),

113

debug: jest.fn(),

114

};

115

116

default:

117

// Fallback to generic mock

118

return createMock(token);

119

}

120

};

121

122

const moduleWithCustomMocking = await Test.createTestingModule({

123

providers: [ComplexService],

124

})

125

.useMocker(advancedMockFactory)

126

.compile();

127

```

128

129

### Integration with Popular Mocking Libraries

130

131

**Jest Auto-Mock:**

132

133

```typescript

134

import { Test } from "@nestjs/testing";

135

136

// Simple Jest-based mock factory

137

const jestMockFactory = (token: any) => {

138

if (typeof token === "function") {

139

const mockClass = jest.fn(() => ({}));

140

mockClass.prototype = Object.create(token.prototype);

141

return new mockClass();

142

}

143

return jest.fn();

144

};

145

146

const module = await Test.createTestingModule({

147

providers: [ServiceUnderTest],

148

})

149

.useMocker(jestMockFactory)

150

.compile();

151

```

152

153

**Sinon Integration:**

154

155

```typescript

156

import * as sinon from "sinon";

157

158

const sinonMockFactory = (token: any) => {

159

if (typeof token === "function") {

160

const mockObj = {};

161

const prototype = token.prototype;

162

163

Object.getOwnPropertyNames(prototype || {}).forEach((method) => {

164

if (method !== "constructor") {

165

mockObj[method] = sinon.stub();

166

}

167

});

168

169

return mockObj;

170

}

171

return sinon.stub();

172

};

173

174

const module = await Test.createTestingModule({

175

providers: [ServiceUnderTest],

176

})

177

.useMocker(sinonMockFactory)

178

.compile();

179

```

180

181

**ts-mockito Integration:**

182

183

```typescript

184

import { mock, instance } from "ts-mockito";

185

186

const tsMockitoFactory = (token: any) => {

187

if (typeof token === "function") {

188

const mockedClass = mock(token);

189

return instance(mockedClass);

190

}

191

return mock();

192

};

193

194

const module = await Test.createTestingModule({

195

providers: [ServiceUnderTest],

196

})

197

.useMocker(tsMockitoFactory)

198

.compile();

199

```

200

201

### Selective Mocking

202

203

Combine automatic mocking with specific overrides:

204

205

```typescript

206

const module = await Test.createTestingModule({

207

providers: [UsersService, EmailService], // EmailService is provided

208

})

209

.overrideProvider(EmailService)

210

.useValue({

211

sendEmail: jest.fn().mockResolvedValue({ sent: true }),

212

})

213

.useMocker(createMock) // Only mocks dependencies not explicitly provided/overridden

214

.compile();

215

216

// EmailService uses the explicit override

217

// Other missing dependencies use the mock factory

218

```

219

220

### Mock Factory Error Handling

221

222

Handle cases where mocking fails or dependencies can't be created:

223

224

```typescript

225

const safeMockFactory = (token: any): any => {

226

try {

227

// Attempt to create a specific mock

228

if (token?.name === "ProblematicService") {

229

return {

230

method1: jest.fn().mockRejectedValue(new Error("Service unavailable")),

231

method2: jest.fn().mockReturnValue(null),

232

};

233

}

234

235

// Default mocking logic

236

return createMock(token);

237

} catch (error) {

238

console.warn(`Failed to mock ${token?.name || token}:`, error.message);

239

240

// Return a minimal mock as fallback

241

return {

242

[Symbol.toStringTag]: `Mock<${token?.name || "Unknown"}>`,

243

};

244

}

245

};

246

247

const module = await Test.createTestingModule({

248

providers: [ServiceWithProblematicDependency],

249

})

250

.useMocker(safeMockFactory)

251

.compile();

252

```

253

254

### Testing with Partial Mocks

255

256

Create partial mocks that preserve some original functionality:

257

258

```typescript

259

import { UsersService } from "./users.service";

260

261

const partialMockFactory = (token: any): any => {

262

if (token === UsersService) {

263

const originalService = new UsersService({} as any);

264

265

return {

266

...originalService,

267

// Override specific methods

268

findUser: jest.fn().mockResolvedValue({ id: 1, name: "Test User" }),

269

// Keep other methods from original implementation

270

};

271

}

272

273

return createMock(token);

274

};

275

```

276

277

## Integration Patterns

278

279

### Async Mock Factories

280

281

```typescript

282

// Mock factory that handles async initialization

283

const asyncMockFactory = (token: any): any => {

284

const mockObj = createMock(token);

285

286

// Ensure async methods return promises

287

Object.keys(mockObj).forEach((key) => {

288

if (typeof mockObj[key] === "function") {

289

// Make all methods async-compatible

290

const originalMock = mockObj[key];

291

mockObj[key] = jest.fn().mockImplementation((...args) => {

292

const result = originalMock(...args);

293

return Promise.resolve(result);

294

});

295

}

296

});

297

298

return mockObj;

299

};

300

```

301

302

### Contextual Mocking

303

304

```typescript

305

// Context-aware mock factory

306

const contextualMockFactory = (token: any): any => {

307

const testName = expect.getState().currentTestName;

308

309

if (testName?.includes("error")) {

310

// Create error-throwing mocks for error tests

311

return createMock(token, {

312

throwError: true,

313

});

314

}

315

316

if (testName?.includes("empty")) {

317

// Create empty-result mocks

318

return createMock(token, {

319

returnEmpty: true,

320

});

321

}

322

323

return createMock(token);

324

};

325

```

326

327

## Types

328

329

```typescript { .api }

330

import { InjectionToken } from "@nestjs/common";

331

332

type MockFactory = (token?: InjectionToken) => any;

333

```