or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdindex.mdmatchers.mdmock-creation.mdspecial-mocking.mdstubbing.mdverification.md

annotations.mddocs/

0

# Annotations

1

2

Annotation-based mock initialization system with automatic dependency injection and comprehensive JUnit integration for streamlined test setup and lifecycle management.

3

4

## Capabilities

5

6

### Core Mock Annotations

7

8

Annotations for automatic mock creation and initialization.

9

10

```kotlin { .api }

11

/**

12

* Creates a mock instance

13

* @property name Optional name for the mock

14

* @property relaxed If true, unstubbed methods return default values

15

* @property relaxUnitFun If true, only Unit-returning methods are relaxed

16

*/

17

@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)

18

annotation class MockK(

19

val name: String = "",

20

val relaxed: Boolean = false,

21

val relaxUnitFun: Boolean = false

22

)

23

24

/**

25

* Creates a relaxed mock instance (equivalent to @MockK(relaxed = true))

26

* @property name Optional name for the mock

27

*/

28

@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)

29

annotation class RelaxedMockK(

30

val name: String = ""

31

)

32

33

/**

34

* Creates a spy instance

35

* @property name Optional name for the spy

36

* @property recordPrivateCalls If true, enables private call recording

37

*/

38

@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)

39

annotation class SpyK(

40

val name: String = "",

41

val recordPrivateCalls: Boolean = true

42

)

43

44

/**

45

* Creates a capturing slot

46

*/

47

@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)

48

annotation class Slot

49

```

50

51

**Usage Examples:**

52

53

```kotlin

54

class UserServiceTest {

55

@MockK

56

lateinit var userRepository: UserRepository

57

58

@RelaxedMockK

59

lateinit var logger: Logger

60

61

@SpyK

62

var emailService = EmailService()

63

64

@MockK(name = "testCache", relaxUnitFun = true)

65

lateinit var cache: CacheService

66

67

@Slot

68

lateinit var userSlot: CapturingSlot<User>

69

70

@BeforeEach

71

fun setUp() {

72

MockKAnnotations.init(this)

73

}

74

75

@Test

76

fun testUserCreation() {

77

// Mocks are automatically initialized

78

every { userRepository.save(capture(userSlot)) } returns User("123", "John")

79

80

val userService = UserService(userRepository, logger, emailService, cache)

81

userService.createUser("John", "john@example.com")

82

83

verify { userRepository.save(any()) }

84

assertEquals("John", userSlot.captured.name)

85

}

86

}

87

```

88

89

### Dependency Injection

90

91

Automatic injection of mocks into test subjects.

92

93

```kotlin { .api }

94

/**

95

* Injects mocks into the annotated property

96

* @property lookupType Strategy for finding mocks to inject

97

* @property injectImmutable If true, can inject into val properties

98

* @property overrideValues If true, overrides existing property values

99

*/

100

@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)

101

annotation class InjectMockKs(

102

val lookupType: InjectionLookupType = InjectionLookupType.BOTH,

103

val injectImmutable: Boolean = false,

104

val overrideValues: Boolean = false

105

)

106

107

enum class InjectionLookupType {

108

/** Inject by property name matching */

109

BY_NAME,

110

111

/** Inject by type matching */

112

BY_TYPE,

113

114

/** Try both name and type matching */

115

BOTH

116

}

117

```

118

119

**Usage Examples:**

120

121

```kotlin

122

class UserService(

123

private val userRepository: UserRepository,

124

private val emailService: EmailService,

125

private val logger: Logger

126

) {

127

fun createUser(name: String, email: String): User {

128

val user = User(generateId(), name, email)

129

userRepository.save(user)

130

emailService.sendWelcomeEmail(user)

131

logger.info("User created: ${user.id}")

132

return user

133

}

134

}

135

136

class UserServiceTest {

137

@MockK

138

lateinit var userRepository: UserRepository

139

140

@MockK

141

lateinit var emailService: EmailService

142

143

@RelaxedMockK

144

lateinit var logger: Logger

145

146

@InjectMockKs

147

lateinit var userService: UserService

148

149

@BeforeEach

150

fun setUp() {

151

MockKAnnotations.init(this)

152

// userService now has mocks injected automatically

153

}

154

155

@Test

156

fun testUserCreation() {

157

every { userRepository.save(any()) } returns User("123", "John", "john@example.com")

158

159

val result = userService.createUser("John", "john@example.com")

160

161

verify { userRepository.save(any()) }

162

verify { emailService.sendWelcomeEmail(any()) }

163

assertEquals("123", result.id)

164

}

165

}

166

```

167

168

### Additional Interface Annotation

169

170

Specify additional interfaces for mocks to implement.

171

172

```kotlin { .api }

173

/**

174

* Specifies additional interfaces for the mock to implement

175

* @property type Interface class to implement

176

*/

177

@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)

178

@Repeatable

179

annotation class AdditionalInterface(

180

val type: KClass<*>

181

)

182

```

183

184

**Usage Examples:**

185

186

```kotlin

187

interface Auditable {

188

fun getAuditInfo(): String

189

}

190

191

interface Serializable

192

193

class ServiceTest {

194

@MockK

195

@AdditionalInterface(Auditable::class)

196

@AdditionalInterface(Serializable::class)

197

lateinit var userService: UserService

198

199

@BeforeEach

200

fun setUp() {

201

MockKAnnotations.init(this)

202

}

203

204

@Test

205

fun testAdditionalInterfaces() {

206

// Mock now implements UserService, Auditable, and Serializable

207

every { (userService as Auditable).getAuditInfo() } returns "audit-info"

208

209

val auditInfo = (userService as Auditable).getAuditInfo()

210

assertEquals("audit-info", auditInfo)

211

212

assertTrue(userService is Serializable)

213

}

214

}

215

```

216

217

### Mock Initialization

218

219

Functions for initializing annotated mocks.

220

221

```kotlin { .api }

222

object MockKAnnotations {

223

/**

224

* Initializes properties annotated with mock annotations

225

* @param obj Objects to initialize annotations for

226

* @param overrideRecordPrivateCalls Override recordPrivateCalls setting

227

* @param relaxUnitFun Global relaxUnitFun setting

228

* @param relaxed Global relaxed setting

229

*/

230

inline fun init(

231

vararg obj: Any,

232

overrideRecordPrivateCalls: Boolean = false,

233

relaxUnitFun: Boolean = false,

234

relaxed: Boolean = false

235

)

236

}

237

```

238

239

**Usage Examples:**

240

241

```kotlin

242

class UserServiceTest {

243

@MockK

244

lateinit var userRepository: UserRepository

245

246

@RelaxedMockK

247

lateinit var logger: Logger

248

249

@SpyK

250

var emailService = EmailService()

251

252

@InjectMockKs

253

lateinit var userService: UserService

254

255

@BeforeEach

256

fun setUp() {

257

// Initialize all annotated properties

258

MockKAnnotations.init(this)

259

}

260

261

// Alternative: Initialize with global settings

262

@BeforeEach

263

fun setUpWithGlobalSettings() {

264

MockKAnnotations.init(

265

this,

266

overrideRecordPrivateCalls = true,

267

relaxUnitFun = true,

268

relaxed = false

269

)

270

}

271

272

// Initialize multiple test objects

273

@BeforeEach

274

fun setUpMultiple() {

275

val helperTest = TestHelper()

276

MockKAnnotations.init(this, helperTest)

277

}

278

}

279

```

280

281

## JUnit Integration

282

283

### JUnit 5 Extension

284

285

Automatic mock lifecycle management for JUnit 5 tests.

286

287

```kotlin { .api }

288

/**

289

* JUnit 5 extension for MockK integration

290

* Provides automatic mock initialization and cleanup

291

*/

292

class MockKExtension :

293

BeforeEachCallback,

294

AfterEachCallback,

295

ParameterResolver

296

```

297

298

**Usage Examples:**

299

300

```kotlin

301

@ExtendWith(MockKExtension::class)

302

class UserServiceTest {

303

@MockK

304

lateinit var userRepository: UserRepository

305

306

@RelaxedMockK

307

lateinit var logger: Logger

308

309

@InjectMockKs

310

lateinit var userService: UserService

311

312

// Mocks are automatically initialized before each test

313

// and cleaned up after each test

314

315

@Test

316

fun testUserCreation() {

317

every { userRepository.save(any()) } returns User("123", "John")

318

319

val result = userService.createUser("John", "john@example.com")

320

321

verify { userRepository.save(any()) }

322

assertEquals("123", result.id)

323

}

324

325

// Parameter injection (JUnit 5 only)

326

@Test

327

fun testWithInjectedMock(@MockK emailService: EmailService) {

328

every { emailService.sendEmail(any(), any()) } returns true

329

330

val result = emailService.sendEmail("test@example.com", "Hello")

331

assertTrue(result)

332

}

333

}

334

```

335

336

### JUnit 5 Configuration Annotations

337

338

Annotations for configuring MockK behavior in JUnit 5 tests.

339

340

```kotlin { .api }

341

/**

342

* Prevents calling unmockkAll after each test

343

*/

344

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)

345

annotation class KeepMocks

346

347

/**

348

* Enables automatic confirmVerified calls after test execution

349

*/

350

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)

351

annotation class ConfirmVerification

352

353

/**

354

* Enables automatic checkUnnecessaryStub calls after test execution

355

*/

356

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)

357

annotation class CheckUnnecessaryStub

358

359

/**

360

* Disables clearAllMocks for thread safety in parallel testing

361

*/

362

@Target(AnnotationTarget.CLASS)

363

annotation class RequireParallelTesting

364

```

365

366

**Usage Examples:**

367

368

```kotlin

369

@ExtendWith(MockKExtension::class)

370

@ConfirmVerification

371

@CheckUnnecessaryStub

372

class UserServiceTest {

373

@MockK

374

lateinit var userRepository: UserRepository

375

376

@InjectMockKs

377

lateinit var userService: UserService

378

379

@Test

380

fun testUserCreation() {

381

every { userRepository.save(any()) } returns User("123", "John")

382

383

userService.createUser("John", "john@example.com")

384

385

verify { userRepository.save(any()) }

386

// confirmVerified and checkUnnecessaryStub called automatically

387

}

388

389

@Test

390

@KeepMocks

391

fun testWithPersistentMocks() {

392

// Mocks are kept after this test

393

every { userRepository.findById("123") } returns User("123", "John")

394

}

395

}

396

397

@ExtendWith(MockKExtension::class)

398

@RequireParallelTesting

399

class ParallelTest {

400

// Safe for parallel execution

401

}

402

```

403

404

### JUnit 4 Rule

405

406

MockK integration for JUnit 4 tests.

407

408

```kotlin { .api }

409

/**

410

* JUnit 4 rule for MockK integration

411

* @param obj Test object to initialize mocks for

412

* @param confirmVerification Enable automatic confirmVerified calls

413

* @param checkUnnecessaryStub Enable automatic checkUnnecessaryStub calls

414

*/

415

class MockKRule(

416

private val obj: Any,

417

private val confirmVerification: Boolean = false,

418

private val checkUnnecessaryStub: Boolean = false

419

) : TestRule

420

```

421

422

**Usage Examples:**

423

424

```kotlin

425

class UserServiceTest {

426

@MockK

427

lateinit var userRepository: UserRepository

428

429

@RelaxedMockK

430

lateinit var logger: Logger

431

432

@InjectMockKs

433

lateinit var userService: UserService

434

435

@get:Rule

436

val mockkRule = MockKRule(this)

437

438

// Alternative with verification checks

439

@get:Rule

440

val strictMockkRule = MockKRule(

441

this,

442

confirmVerification = true,

443

checkUnnecessaryStub = true

444

)

445

446

@Test

447

fun testUserCreation() {

448

every { userRepository.save(any()) } returns User("123", "John")

449

450

val result = userService.createUser("John", "john@example.com")

451

452

verify { userRepository.save(any()) }

453

assertEquals("123", result.id)

454

}

455

}

456

```

457

458

### Best Practices

459

460

Recommended patterns for using MockK annotations effectively.

461

462

```kotlin

463

// Recommended test structure

464

@ExtendWith(MockKExtension::class)

465

class UserServiceTest {

466

// Required dependencies as mocks

467

@MockK

468

lateinit var userRepository: UserRepository

469

470

@MockK

471

lateinit var emailService: EmailService

472

473

// Optional dependencies as relaxed mocks

474

@RelaxedMockK

475

lateinit var logger: Logger

476

477

@RelaxedMockK

478

lateinit var metrics: MetricsService

479

480

// Test subject with automatic injection

481

@InjectMockKs

482

lateinit var userService: UserService

483

484

// Capture slots for argument verification

485

@Slot

486

lateinit var userSlot: CapturingSlot<User>

487

488

@Slot

489

lateinit var emailSlot: CapturingSlot<String>

490

491

@Test

492

fun testCompleteUserFlow() {

493

// Setup

494

every { userRepository.save(capture(userSlot)) } returns User("123", "John")

495

every { emailService.sendWelcomeEmail(capture(emailSlot)) } returns true

496

497

// Execute

498

val result = userService.createUser("John", "john@example.com")

499

500

// Verify

501

verify { userRepository.save(any()) }

502

verify { emailService.sendWelcomeEmail("john@example.com") }

503

504

assertEquals("John", userSlot.captured.name)

505

assertEquals("john@example.com", emailSlot.captured)

506

}

507

}

508

```