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

matchers.mddocs/

0

# Matchers

1

2

Sophisticated argument matching system with built-in matchers for equality, comparison, type checking, capturing, and logical operations to create flexible and powerful mock interactions.

3

4

## Capabilities

5

6

### Basic Matchers

7

8

Fundamental argument matching functions for common scenarios.

9

10

```kotlin { .api }

11

/**

12

* Matches any argument of the specified type

13

*/

14

fun <T> any(): T

15

16

/**

17

* Matches any nullable argument

18

*/

19

fun <T> anyNullable(): T?

20

21

/**

22

* Matches arguments equal to the specified value

23

* @param value Value to match against

24

* @param inverse If true, matches non-equal values

25

*/

26

fun <T> eq(value: T, inverse: Boolean = false): T

27

28

/**

29

* Matches arguments not equal to the specified value

30

* @param value Value to not match

31

*/

32

fun <T> neq(value: T): T

33

```

34

35

**Usage Examples:**

36

37

```kotlin

38

val userService = mockk<UserService>()

39

40

// Match any argument

41

every { userService.getUserById(any()) } returns User("default", "Default User")

42

43

// Match specific value

44

every { userService.getUserById(eq("123")) } returns User("123", "John")

45

46

// Match not equal to value

47

every { userService.getUserById(neq("admin")) } returns User("user", "Regular User")

48

49

// Use in verification

50

verify { userService.saveUser(any()) }

51

verify { userService.getUserById(eq("123")) }

52

```

53

54

### Reference Equality Matchers

55

56

Matchers based on reference equality rather than value equality.

57

58

```kotlin { .api }

59

/**

60

* Matches arguments with same reference as the specified value

61

* @param value Reference to match against

62

* @param inverse If true, matches different references

63

*/

64

fun <T> refEq(value: T, inverse: Boolean = false): T

65

66

/**

67

* Matches arguments with different reference than the specified value

68

* @param value Reference to not match

69

*/

70

fun <T> nrefEq(value: T): T

71

```

72

73

**Usage Examples:**

74

75

```kotlin

76

val userService = mockk<UserService>()

77

val specificUser = User("123", "John")

78

79

// Match same reference

80

every { userService.processUser(refEq(specificUser)) } returns "processed"

81

82

// Match different reference

83

every { userService.processUser(nrefEq(specificUser)) } returns "different object"

84

85

// Verification with reference equality

86

verify { userService.processUser(refEq(specificUser)) }

87

```

88

89

### Comparison Matchers

90

91

Matchers for numerical and comparable value comparisons.

92

93

```kotlin { .api }

94

/**

95

* Matches arguments greater than the specified value

96

* @param value Comparison value

97

* @param andEquals If true, includes equal values (>=)

98

*/

99

fun <T : Comparable<T>> more(value: T, andEquals: Boolean = false): T

100

101

/**

102

* Matches arguments less than the specified value

103

* @param value Comparison value

104

* @param andEquals If true, includes equal values (<=)

105

*/

106

fun <T : Comparable<T>> less(value: T, andEquals: Boolean = false): T

107

108

/**

109

* Matches arguments within the specified range

110

* @param from Range start value

111

* @param to Range end value

112

* @param fromInclusive Include start value (default: true)

113

* @param toInclusive Include end value (default: true)

114

*/

115

fun <T : Comparable<T>> range(

116

from: T,

117

to: T,

118

fromInclusive: Boolean = true,

119

toInclusive: Boolean = true

120

): T

121

122

/**

123

* Matches using Comparable.compareTo for equality

124

* @param value Value to compare against

125

*/

126

fun <T : Comparable<T>> cmpEq(value: T): T

127

```

128

129

**Usage Examples:**

130

131

```kotlin

132

val userService = mockk<UserService>()

133

134

// Numerical comparisons

135

every { userService.getUsersWithAge(more(18)) } returns listOf(/* adults */)

136

every { userService.getUsersWithAge(less(65, andEquals = true)) } returns listOf(/* non-seniors */)

137

every { userService.getUsersWithAge(range(18, 65)) } returns listOf(/* working age */)

138

139

// String comparisons

140

every { userService.getUsersWithNameAfter(more("M")) } returns listOf(/* names N-Z */)

141

142

// Verification with comparisons

143

verify { userService.processUsersWithScore(more(80)) }

144

```

145

146

### Type Checking Matchers

147

148

Matchers for type-based argument matching.

149

150

```kotlin { .api }

151

/**

152

* Matches arguments of the specified type

153

*/

154

inline fun <reified T> ofType(): T

155

156

/**

157

* Matches null values

158

* @param inverse If true, matches non-null values

159

*/

160

fun <T> isNull(inverse: Boolean = false): T?

161

```

162

163

**Usage Examples:**

164

165

```kotlin

166

val userService = mockk<UserService>()

167

168

// Match by type

169

every { userService.processEntity(ofType<User>()) } returns "user processed"

170

every { userService.processEntity(ofType<Admin>()) } returns "admin processed"

171

172

// Match null/non-null

173

every { userService.processOptionalData(isNull()) } returns "no data"

174

every { userService.processOptionalData(isNull(inverse = true)) } returns "has data"

175

176

// Verification with type matching

177

verify { userService.processEntity(ofType<User>()) }

178

```

179

180

### Logical Combinators

181

182

Matchers for combining multiple matching conditions.

183

184

```kotlin { .api }

185

/**

186

* Matches arguments that satisfy both matchers (logical AND)

187

* @param left First matcher

188

* @param right Second matcher

189

*/

190

fun <T> and(left: T, right: T): T

191

192

/**

193

* Matches arguments that satisfy either matcher (logical OR)

194

* @param left First matcher

195

* @param right Second matcher

196

*/

197

fun <T> or(left: T, right: T): T

198

199

/**

200

* Matches arguments that do NOT satisfy the matcher (logical NOT)

201

* @param value Matcher to negate

202

*/

203

fun <T> not(value: T): T

204

```

205

206

**Usage Examples:**

207

208

```kotlin

209

val userService = mockk<UserService>()

210

211

// Logical AND - age between 18-65 AND name starts with "J"

212

every {

213

userService.processUser(and(

214

match { it.age in 18..65 },

215

match { it.name.startsWith("J") }

216

))

217

} returns "processed special user"

218

219

// Logical OR - either admin or premium user

220

every {

221

userService.processUser(or(

222

match { it.type == UserType.ADMIN },

223

match { it.isPremium }

224

))

225

} returns "processed privileged user"

226

227

// Logical NOT - not a test user

228

every { userService.processUser(not(match { it.isTestUser })) } returns "processed real user"

229

```

230

231

### Capturing Matchers

232

233

Matchers that capture arguments for later inspection.

234

235

```kotlin { .api }

236

/**

237

* Captures argument to a list

238

* @param lst Mutable list to capture values into

239

*/

240

fun <T> capture(lst: MutableList<T>): T

241

242

/**

243

* Captures argument to a capturing slot

244

* @param slot CapturingSlot to capture value into

245

*/

246

fun <T> capture(slot: CapturingSlot<T>): T

247

248

/**

249

* Captures nullable argument to a list

250

* @param lst Mutable list to capture values into

251

*/

252

fun <T> captureNullable(lst: MutableList<T?>): T?

253

254

/**

255

* Captures nullable argument to a capturing slot

256

* @param slot CapturingSlot to capture value into

257

*/

258

fun <T> captureNullable(slot: CapturingSlot<T?>): T?

259

```

260

261

**Usage Examples:**

262

263

```kotlin

264

val userService = mockk<UserService>()

265

val capturedUsers = mutableListOf<User>()

266

val userSlot = slot<User>()

267

268

// Capture to list

269

every { userService.saveUser(capture(capturedUsers)) } returns "saved"

270

271

// Capture to slot

272

every { userService.updateUser(capture(userSlot)) } returns "updated"

273

274

// Make calls

275

userService.saveUser(User("1", "John"))

276

userService.saveUser(User("2", "Jane"))

277

userService.updateUser(User("3", "Bob"))

278

279

// Access captured values

280

val allSavedUsers = capturedUsers // [User("1", "John"), User("2", "Jane")]

281

val lastUpdatedUser = userSlot.captured // User("3", "Bob")

282

```

283

284

### Custom Matchers

285

286

Create custom matching logic using the match function.

287

288

```kotlin { .api }

289

/**

290

* Matches arguments using custom matcher logic

291

* @param matcher Custom Matcher implementation

292

*/

293

fun <T> match(matcher: Matcher<T>): T

294

295

/**

296

* Matches arguments using lambda-based matching

297

* @param predicate Lambda that returns true for matching arguments

298

*/

299

inline fun <reified T> match(noinline predicate: (T?) -> Boolean): T

300

301

interface Matcher<in T> {

302

fun match(arg: T?): Boolean

303

fun substitute(map: Map<Any, Any>): Matcher<T>

304

}

305

```

306

307

**Usage Examples:**

308

309

```kotlin

310

val userService = mockk<UserService>()

311

312

// Lambda-based matching

313

every {

314

userService.processUser(match { user ->

315

user != null && user.name.length > 5 && user.age > 18

316

})

317

} returns "processed valid user"

318

319

// Custom Matcher implementation

320

class EmailMatcher : Matcher<String> {

321

override fun match(arg: String?): Boolean {

322

return arg?.contains("@") == true

323

}

324

325

override fun substitute(map: Map<Any, Any>): Matcher<String> = this

326

}

327

328

every { userService.sendEmail(match(EmailMatcher())) } returns "email sent"

329

330

// Verification with custom matching

331

verify {

332

userService.processUser(match { it?.name?.startsWith("J") == true })

333

}

334

```

335

336

### Array and Collection Matchers

337

338

Specialized matchers for arrays and collections.

339

340

```kotlin { .api }

341

/**

342

* Matches any vararg arguments

343

*/

344

fun <T> anyVararg(): Array<T>

345

346

/**

347

* Matches varargs where all elements satisfy the condition

348

* @param matcher Matcher that all elements must satisfy

349

*/

350

fun <T> varargAll(matcher: T): Array<T>

351

352

/**

353

* Matches varargs where any element satisfies the condition

354

* @param matcher Matcher that at least one element must satisfy

355

*/

356

fun <T> varargAny(matcher: T): Array<T>

357

358

// Primitive array matchers

359

fun anyIntVararg(): IntArray

360

fun anyBooleanVararg(): BooleanArray

361

fun anyByteVararg(): ByteArray

362

fun anyCharVararg(): CharArray

363

fun anyShortVararg(): ShortArray

364

fun anyLongVararg(): LongArray

365

fun anyFloatVararg(): FloatArray

366

fun anyDoubleVararg(): DoubleArray

367

```

368

369

**Usage Examples:**

370

371

```kotlin

372

interface LogService {

373

fun log(level: String, vararg messages: String)

374

fun logNumbers(vararg numbers: Int)

375

}

376

377

val logService = mockk<LogService>()

378

379

// Match any varargs

380

every { logService.log("INFO", *anyVararg()) } just Runs

381

382

// Match varargs with conditions

383

every {

384

logService.log("ERROR", *varargAll(match { it.contains("error") }))

385

} just Runs

386

387

// Match primitive varargs

388

every { logService.logNumbers(*anyIntVararg()) } just Runs

389

390

// Verification with varargs

391

verify { logService.log("INFO", *anyVararg()) }

392

```

393

394

### Function and Lambda Matchers

395

396

Matchers for function types and lambda arguments.

397

398

```kotlin { .api }

399

/**

400

* Captures lambda functions for execution

401

*/

402

fun <T> captureLambda(): T

403

404

/**

405

* Captures coroutine functions

406

*/

407

fun <T> captureCoroutine(): T

408

409

/**

410

* Matches function invocations (up to 22 parameters)

411

*/

412

fun invoke(): Function0<*>

413

fun <T1> invoke(arg1: T1): Function1<T1, *>

414

fun <T1, T2> invoke(arg1: T1, arg2: T2): Function2<T1, T2, *>

415

// ... up to Function22

416

417

/**

418

* Matches coroutine function invocations

419

*/

420

fun coInvoke(): suspend () -> Any?

421

fun <T1> coInvoke(arg1: T1): suspend (T1) -> Any?

422

// ... and so on

423

```

424

425

**Usage Examples:**

426

427

```kotlin

428

interface CallbackService {

429

fun processWithCallback(data: String, callback: (String) -> Unit)

430

fun processAsync(data: String, callback: suspend (String) -> Unit)

431

}

432

433

val callbackService = mockk<CallbackService>()

434

val lambdaSlot = slot<(String) -> Unit>()

435

436

// Capture lambda for later execution

437

every {

438

callbackService.processWithCallback(any(), captureLambda())

439

} answers {

440

val callback = secondArg<(String) -> Unit>()

441

callback("processed: ${firstArg<String>()}")

442

}

443

444

// Match function invocation

445

every {

446

callbackService.processWithCallback("test", invoke("result"))

447

} just Runs

448

449

// Verification with function matching

450

verify {

451

callbackService.processWithCallback("test", invoke("result"))

452

}

453

```

454

455

### Universal Matchers

456

457

Matchers that handle special cases and universal matching.

458

459

```kotlin { .api }

460

/**

461

* Matches any argument (most permissive matcher)

462

*/

463

fun <T> allAny(): T

464

```

465

466

**Usage Examples:**

467

468

```kotlin

469

val userService = mockk<UserService>()

470

471

// Most permissive matching

472

every { userService.complexMethod(allAny(), allAny(), allAny()) } returns "result"

473

474

// Useful when exact matching is difficult

475

verify { userService.complexMethod(allAny(), allAny(), allAny()) }

476

```