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

stubbing.mddocs/

0

# Stubbing

1

2

Behavior definition system for specifying how mocks should respond to method calls, with comprehensive support for return values, exceptions, custom answers, and coroutine operations.

3

4

## Capabilities

5

6

### Basic Stubbing

7

8

Core stubbing functions for defining mock behavior.

9

10

```kotlin { .api }

11

/**

12

* Starts a stubbing block for defining mock behavior

13

* @param stubBlock Block containing the method call to stub

14

* @return MockKStubScope for specifying the response

15

*/

16

fun <T> every(stubBlock: MockKMatcherScope.() -> T): MockKStubScope<T, T>

17

18

/**

19

* Coroutine version of every for suspend functions

20

* @param stubBlock Block containing the suspend method call to stub

21

* @return MockKStubScope for specifying the response

22

*/

23

fun <T> coEvery(stubBlock: suspend MockKMatcherScope.() -> T): MockKStubScope<T, T>

24

25

/**

26

* Shortcut for stubbing Unit-returning functions

27

* @param stubBlock Block containing the Unit method call to stub

28

*/

29

fun justRun(stubBlock: MockKMatcherScope.() -> Unit)

30

31

/**

32

* Coroutine version of justRun for suspend Unit functions

33

* @param stubBlock Block containing the suspend Unit method call to stub

34

*/

35

fun coJustRun(stubBlock: suspend MockKMatcherScope.() -> Unit)

36

```

37

38

**Usage Examples:**

39

40

```kotlin

41

val userService = mockk<UserService>()

42

43

// Basic return value stubbing

44

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

45

46

// Coroutine stubbing

47

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

48

49

// Unit function stubbing

50

justRun { userService.deleteUser("123") }

51

52

// Suspend unit function stubbing

53

coJustRun { userService.deleteUserAsync("123") }

54

```

55

56

### Stub Responses

57

58

Different ways to specify how stubbed methods should respond.

59

60

```kotlin { .api }

61

interface MockKStubScope<T, B> {

62

/** Returns a constant value */

63

infix fun returns(returnValue: T): MockKAdditionalAnswerScope<T, B>

64

65

/** Returns different values in sequence */

66

infix fun returnsMany(values: List<T>): MockKAdditionalAnswerScope<T, B>

67

68

/** Returns the nth argument passed to the method */

69

infix fun returnsArgument(n: Int): MockKAdditionalAnswerScope<T, B>

70

71

/** Throws an exception */

72

infix fun throws(ex: Throwable): MockKAdditionalAnswerScope<T, B>

73

74

/** Throws different exceptions in sequence */

75

infix fun throwsMany(exList: List<Throwable>): MockKAdditionalAnswerScope<T, B>

76

77

/** Provides a custom answer implementation */

78

infix fun answers(answer: Answer<T>): MockKAdditionalAnswerScope<T, B>

79

80

/** Provides a lambda-based answer */

81

infix fun answers(answer: MockKAnswerScope<T, B>.(Call) -> T): MockKAdditionalAnswerScope<T, B>

82

83

/** Provides a coroutine-based answer */

84

infix fun coAnswers(answer: suspend MockKAnswerScope<T, B>.(Call) -> T): MockKAdditionalAnswerScope<T, B>

85

}

86

```

87

88

**Usage Examples:**

89

90

```kotlin

91

val userService = mockk<UserService>()

92

93

// Return constant value

94

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

95

96

// Return sequence of values

97

every { userService.getNextId() } returnsMany listOf("1", "2", "3")

98

99

// Return argument

100

every { userService.echoId(any()) } returnsArgument 0

101

102

// Throw exception

103

every { userService.getUserById("invalid") } throws UserNotFoundException()

104

105

// Throw sequence of exceptions

106

every { userService.unstableOperation() } throwsMany listOf(

107

NetworkException(),

108

TimeoutException()

109

)

110

111

// Custom answer with call information

112

every { userService.processUser(any()) } answers {

113

val user = firstArg<User>()

114

User(user.id, user.name.uppercase())

115

}

116

117

// Coroutine answer

118

coEvery { userService.processUserAsync(any()) } coAnswers {

119

delay(100)

120

val user = firstArg<User>()

121

User(user.id, user.name.uppercase())

122

}

123

```

124

125

### Answer Scopes

126

127

Access to call information within custom answers.

128

129

```kotlin { .api }

130

abstract class MockKAnswerScope<T, B> {

131

/** Current call information */

132

val call: Call

133

134

/** Arguments passed to the method */

135

val args: List<Any?>

136

137

/** Number of arguments */

138

val nArgs: Int

139

140

/** Mock object being called */

141

val self: Any

142

143

/** Method being called */

144

val method: MethodDescription

145

146

/** Access to first argument with type casting */

147

fun <T> firstArg(): T

148

149

/** Access to second argument with type casting */

150

fun <T> secondArg(): T

151

152

/** Access to third argument with type casting */

153

fun <T> thirdArg(): T

154

155

/** Access to last argument with type casting */

156

fun <T> lastArg(): T

157

158

/** Access to nth argument with type casting */

159

fun <T> arg(n: Int): T

160

161

/** For spies - calls the original implementation */

162

fun callOriginal(): T

163

}

164

```

165

166

**Usage Examples:**

167

168

```kotlin

169

val userService = spyk<UserService>()

170

171

// Access arguments in answer

172

every { userService.createUser(any(), any()) } answers {

173

val name = firstArg<String>()

174

val email = secondArg<String>()

175

User(generateId(), name, email)

176

}

177

178

// Call original implementation (for spies)

179

every { userService.validateUser(any()) } answers {

180

val user = firstArg<User>()

181

if (user.id == "test") {

182

true // Custom behavior for test user

183

} else {

184

callOriginal() // Use real implementation

185

}

186

}

187

188

// Access call metadata

189

every { userService.logOperation(any()) } answers {

190

val operation = firstArg<String>()

191

logger.info("Mock ${method.name} called with: $operation")

192

callOriginal()

193

}

194

```

195

196

### Special Answer Types

197

198

Pre-built answer implementations for common scenarios.

199

200

```kotlin { .api }

201

object Runs

202

object Awaits

203

204

// Used with 'just' infix function

205

infix fun MockKStubScope<Unit, *>.just(runs: Runs)

206

infix fun MockKStubScope<Unit, *>.just(awaits: Awaits)

207

```

208

209

**Usage Examples:**

210

211

```kotlin

212

// Equivalent to justRun

213

every { userService.deleteUser(any()) } just Runs

214

215

// For suspend functions that never return

216

coEvery { userService.waitForever() } just Awaits

217

```

218

219

### Argument Capture in Stubbing

220

221

Capturing arguments during stubbing for later inspection.

222

223

```kotlin { .api }

224

/**

225

* Creates a capturing slot for single values

226

*/

227

inline fun <reified T : Any?> slot(): CapturingSlot<T>

228

229

class CapturingSlot<T> {

230

val captured: T

231

val isCaptured: Boolean

232

val isNull: Boolean

233

fun clear()

234

}

235

```

236

237

**Usage Examples:**

238

239

```kotlin

240

val userService = mockk<UserService>()

241

val userSlot = slot<User>()

242

val idSlot = slot<String>()

243

244

// Capture argument during stubbing

245

every { userService.saveUser(capture(userSlot)) } returns "user-id"

246

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

247

248

// Use the mock

249

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

250

userService.getUserById("123")

251

252

// Access captured values

253

val capturedUser = userSlot.captured // User("123", "John")

254

val capturedId = idSlot.captured // "123"

255

```

256

257

### Property Stubbing

258

259

Stubbing property access on mocks.

260

261

```kotlin { .api }

262

interface MockKStubScope<T, B> {

263

/** Specify property type for proper stubbing */

264

fun <K> propertyType(): MockKStubScope<K, B>

265

266

/** Specify nullable property type */

267

fun <K> nullablePropertyType(): MockKStubScope<K?, B>

268

}

269

```

270

271

**Usage Examples:**

272

273

```kotlin

274

val userService = mockk<UserService>()

275

276

// Property getter stubbing

277

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

278

279

// Property setter stubbing

280

every { userService.currentUser = any() } just Runs

281

282

// Property with type specification

283

every { userService.userCount } propertyType<Int>() returns 42

284

```

285

286

### Chained Stubbing

287

288

Multiple stub configurations for the same method call.

289

290

```kotlin { .api }

291

interface MockKAdditionalAnswerScope<T, B> {

292

/** Add another answer that will be used in subsequent calls */

293

infix fun andThen(answer: T): MockKAdditionalAnswerScope<T, B>

294

295

/** Add another answer with different behavior */

296

infix fun andThenThrows(ex: Throwable): MockKAdditionalAnswerScope<T, B>

297

}

298

```

299

300

**Usage Examples:**

301

302

```kotlin

303

val userService = mockk<UserService>()

304

305

// Chain different responses

306

every { userService.getUser() } returns User("1", "John") andThen User("2", "Jane")

307

308

// Mix returns and exceptions

309

every { userService.unstableOperation() } returns "success" andThenThrows NetworkException()

310

311

// Complex chaining

312

every { userService.getData() } returns "data1" andThen "data2" andThenThrows TimeoutException()

313

```