SMokK
A little bit scary library for mocking suspendable functions in Kotlin :-)
Example
suspend fun getUserDetailsFast(
userId: Int,
fetchUserDetails: suspend (Int) -> String?,
getCachedUserDetails: suspend (Int) -> String?,
putCachedUserDetails: suspend (Int, String) -> Unit
): String? = coroutineScope {
val cached = async { getCachedUserDetails(userId) }
val new = async { fetchUserDetails(userId) }
cached.await()?.also { new.cancel() } ?: new.await()?.also { putCachedUserDetails(userId, it) }
}
@Test
fun getUserDetailsFastTest() {
uspek {
"On getUserDetailsFast" o {
val fetchUserDetails = smokk<Int, String?>()
val getCachedUserDetails = smokk<Int, String?>()
val putCachedUserDetails = smokk<Int, String, Unit>()
val deferred = GlobalScope.async(Dispatchers.Unconfined) {
runCatching {
getUserDetailsFast(
userId = 7,
fetchUserDetails = fetchUserDetails::invoke,
getCachedUserDetails = getCachedUserDetails::invoke,
putCachedUserDetails = putCachedUserDetails::invoke
)
}
}
"is active" o { deferred.isActive eq true }
"getting cached details started" o { getCachedUserDetails.invocations eq listOf(7) }
"fetching details started too" o { fetchUserDetails.invocations eq listOf() }
o {
getCachedUserDetails.resume()
o { deferred.isActive eq }
o {
fetchUserDetails.resumeWithException(CancellationException())
o { deferred.getCompleted() eq success() }
}
}
}
}
}
Full examples are available in the kotlinsample directory