Comprehensive mocking library for Kotlin with native coroutine support and advanced DSL features.
—
Sophisticated argument matching system with built-in matchers for equality, comparison, type checking, capturing, and logical operations to create flexible and powerful mock interactions.
Fundamental argument matching functions for common scenarios.
/**
* Matches any argument of the specified type
*/
fun <T> any(): T
/**
* Matches any nullable argument
*/
fun <T> anyNullable(): T?
/**
* Matches arguments equal to the specified value
* @param value Value to match against
* @param inverse If true, matches non-equal values
*/
fun <T> eq(value: T, inverse: Boolean = false): T
/**
* Matches arguments not equal to the specified value
* @param value Value to not match
*/
fun <T> neq(value: T): TUsage Examples:
val userService = mockk<UserService>()
// Match any argument
every { userService.getUserById(any()) } returns User("default", "Default User")
// Match specific value
every { userService.getUserById(eq("123")) } returns User("123", "John")
// Match not equal to value
every { userService.getUserById(neq("admin")) } returns User("user", "Regular User")
// Use in verification
verify { userService.saveUser(any()) }
verify { userService.getUserById(eq("123")) }Matchers based on reference equality rather than value equality.
/**
* Matches arguments with same reference as the specified value
* @param value Reference to match against
* @param inverse If true, matches different references
*/
fun <T> refEq(value: T, inverse: Boolean = false): T
/**
* Matches arguments with different reference than the specified value
* @param value Reference to not match
*/
fun <T> nrefEq(value: T): TUsage Examples:
val userService = mockk<UserService>()
val specificUser = User("123", "John")
// Match same reference
every { userService.processUser(refEq(specificUser)) } returns "processed"
// Match different reference
every { userService.processUser(nrefEq(specificUser)) } returns "different object"
// Verification with reference equality
verify { userService.processUser(refEq(specificUser)) }Matchers for numerical and comparable value comparisons.
/**
* Matches arguments greater than the specified value
* @param value Comparison value
* @param andEquals If true, includes equal values (>=)
*/
fun <T : Comparable<T>> more(value: T, andEquals: Boolean = false): T
/**
* Matches arguments less than the specified value
* @param value Comparison value
* @param andEquals If true, includes equal values (<=)
*/
fun <T : Comparable<T>> less(value: T, andEquals: Boolean = false): T
/**
* Matches arguments within the specified range
* @param from Range start value
* @param to Range end value
* @param fromInclusive Include start value (default: true)
* @param toInclusive Include end value (default: true)
*/
fun <T : Comparable<T>> range(
from: T,
to: T,
fromInclusive: Boolean = true,
toInclusive: Boolean = true
): T
/**
* Matches using Comparable.compareTo for equality
* @param value Value to compare against
*/
fun <T : Comparable<T>> cmpEq(value: T): TUsage Examples:
val userService = mockk<UserService>()
// Numerical comparisons
every { userService.getUsersWithAge(more(18)) } returns listOf(/* adults */)
every { userService.getUsersWithAge(less(65, andEquals = true)) } returns listOf(/* non-seniors */)
every { userService.getUsersWithAge(range(18, 65)) } returns listOf(/* working age */)
// String comparisons
every { userService.getUsersWithNameAfter(more("M")) } returns listOf(/* names N-Z */)
// Verification with comparisons
verify { userService.processUsersWithScore(more(80)) }Matchers for type-based argument matching.
/**
* Matches arguments of the specified type
*/
inline fun <reified T> ofType(): T
/**
* Matches null values
* @param inverse If true, matches non-null values
*/
fun <T> isNull(inverse: Boolean = false): T?Usage Examples:
val userService = mockk<UserService>()
// Match by type
every { userService.processEntity(ofType<User>()) } returns "user processed"
every { userService.processEntity(ofType<Admin>()) } returns "admin processed"
// Match null/non-null
every { userService.processOptionalData(isNull()) } returns "no data"
every { userService.processOptionalData(isNull(inverse = true)) } returns "has data"
// Verification with type matching
verify { userService.processEntity(ofType<User>()) }Matchers for combining multiple matching conditions.
/**
* Matches arguments that satisfy both matchers (logical AND)
* @param left First matcher
* @param right Second matcher
*/
fun <T> and(left: T, right: T): T
/**
* Matches arguments that satisfy either matcher (logical OR)
* @param left First matcher
* @param right Second matcher
*/
fun <T> or(left: T, right: T): T
/**
* Matches arguments that do NOT satisfy the matcher (logical NOT)
* @param value Matcher to negate
*/
fun <T> not(value: T): TUsage Examples:
val userService = mockk<UserService>()
// Logical AND - age between 18-65 AND name starts with "J"
every {
userService.processUser(and(
match { it.age in 18..65 },
match { it.name.startsWith("J") }
))
} returns "processed special user"
// Logical OR - either admin or premium user
every {
userService.processUser(or(
match { it.type == UserType.ADMIN },
match { it.isPremium }
))
} returns "processed privileged user"
// Logical NOT - not a test user
every { userService.processUser(not(match { it.isTestUser })) } returns "processed real user"Matchers that capture arguments for later inspection.
/**
* Captures argument to a list
* @param lst Mutable list to capture values into
*/
fun <T> capture(lst: MutableList<T>): T
/**
* Captures argument to a capturing slot
* @param slot CapturingSlot to capture value into
*/
fun <T> capture(slot: CapturingSlot<T>): T
/**
* Captures nullable argument to a list
* @param lst Mutable list to capture values into
*/
fun <T> captureNullable(lst: MutableList<T?>): T?
/**
* Captures nullable argument to a capturing slot
* @param slot CapturingSlot to capture value into
*/
fun <T> captureNullable(slot: CapturingSlot<T?>): T?Usage Examples:
val userService = mockk<UserService>()
val capturedUsers = mutableListOf<User>()
val userSlot = slot<User>()
// Capture to list
every { userService.saveUser(capture(capturedUsers)) } returns "saved"
// Capture to slot
every { userService.updateUser(capture(userSlot)) } returns "updated"
// Make calls
userService.saveUser(User("1", "John"))
userService.saveUser(User("2", "Jane"))
userService.updateUser(User("3", "Bob"))
// Access captured values
val allSavedUsers = capturedUsers // [User("1", "John"), User("2", "Jane")]
val lastUpdatedUser = userSlot.captured // User("3", "Bob")Create custom matching logic using the match function.
/**
* Matches arguments using custom matcher logic
* @param matcher Custom Matcher implementation
*/
fun <T> match(matcher: Matcher<T>): T
/**
* Matches arguments using lambda-based matching
* @param predicate Lambda that returns true for matching arguments
*/
inline fun <reified T> match(noinline predicate: (T?) -> Boolean): T
interface Matcher<in T> {
fun match(arg: T?): Boolean
fun substitute(map: Map<Any, Any>): Matcher<T>
}Usage Examples:
val userService = mockk<UserService>()
// Lambda-based matching
every {
userService.processUser(match { user ->
user != null && user.name.length > 5 && user.age > 18
})
} returns "processed valid user"
// Custom Matcher implementation
class EmailMatcher : Matcher<String> {
override fun match(arg: String?): Boolean {
return arg?.contains("@") == true
}
override fun substitute(map: Map<Any, Any>): Matcher<String> = this
}
every { userService.sendEmail(match(EmailMatcher())) } returns "email sent"
// Verification with custom matching
verify {
userService.processUser(match { it?.name?.startsWith("J") == true })
}Specialized matchers for arrays and collections.
/**
* Matches any vararg arguments
*/
fun <T> anyVararg(): Array<T>
/**
* Matches varargs where all elements satisfy the condition
* @param matcher Matcher that all elements must satisfy
*/
fun <T> varargAll(matcher: T): Array<T>
/**
* Matches varargs where any element satisfies the condition
* @param matcher Matcher that at least one element must satisfy
*/
fun <T> varargAny(matcher: T): Array<T>
// Primitive array matchers
fun anyIntVararg(): IntArray
fun anyBooleanVararg(): BooleanArray
fun anyByteVararg(): ByteArray
fun anyCharVararg(): CharArray
fun anyShortVararg(): ShortArray
fun anyLongVararg(): LongArray
fun anyFloatVararg(): FloatArray
fun anyDoubleVararg(): DoubleArrayUsage Examples:
interface LogService {
fun log(level: String, vararg messages: String)
fun logNumbers(vararg numbers: Int)
}
val logService = mockk<LogService>()
// Match any varargs
every { logService.log("INFO", *anyVararg()) } just Runs
// Match varargs with conditions
every {
logService.log("ERROR", *varargAll(match { it.contains("error") }))
} just Runs
// Match primitive varargs
every { logService.logNumbers(*anyIntVararg()) } just Runs
// Verification with varargs
verify { logService.log("INFO", *anyVararg()) }Matchers for function types and lambda arguments.
/**
* Captures lambda functions for execution
*/
fun <T> captureLambda(): T
/**
* Captures coroutine functions
*/
fun <T> captureCoroutine(): T
/**
* Matches function invocations (up to 22 parameters)
*/
fun invoke(): Function0<*>
fun <T1> invoke(arg1: T1): Function1<T1, *>
fun <T1, T2> invoke(arg1: T1, arg2: T2): Function2<T1, T2, *>
// ... up to Function22
/**
* Matches coroutine function invocations
*/
fun coInvoke(): suspend () -> Any?
fun <T1> coInvoke(arg1: T1): suspend (T1) -> Any?
// ... and so onUsage Examples:
interface CallbackService {
fun processWithCallback(data: String, callback: (String) -> Unit)
fun processAsync(data: String, callback: suspend (String) -> Unit)
}
val callbackService = mockk<CallbackService>()
val lambdaSlot = slot<(String) -> Unit>()
// Capture lambda for later execution
every {
callbackService.processWithCallback(any(), captureLambda())
} answers {
val callback = secondArg<(String) -> Unit>()
callback("processed: ${firstArg<String>()}")
}
// Match function invocation
every {
callbackService.processWithCallback("test", invoke("result"))
} just Runs
// Verification with function matching
verify {
callbackService.processWithCallback("test", invoke("result"))
}Matchers that handle special cases and universal matching.
/**
* Matches any argument (most permissive matcher)
*/
fun <T> allAny(): TUsage Examples:
val userService = mockk<UserService>()
// Most permissive matching
every { userService.complexMethod(allAny(), allAny(), allAny()) } returns "result"
// Useful when exact matching is difficult
verify { userService.complexMethod(allAny(), allAny(), allAny()) }Install with Tessl CLI
npx tessl i tessl/maven-io-mockk--mockk