Uzzu::Blog

Software Design, and my life.

Kotlin MPPでのcoroutines test

そのうちリリースされると思うけど、まだっぽいのでメモ。

JVM環境では runBlocking を使う事でCoroutinesのテストをかけていたけど、 runBlocking はcoroutines-core (jvm)の機能なので、 Kotlin MPPでのcommon moduleでCoroutinesのテストをするにはいい感じにやってやる必要があります。

common

dependencies: kotlin-test-common, kotlinx-coroutines-core-common

import kotlinx.coroutines.CoroutineScope
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* To use test suspending function
* @param expected A conditions of expected exception. Default is null (unchecked)
* @param context coroutine context to use
* @param block testing body
*/
expect fun runTest(
expected: ((Throwable) -> Boolean)? = null,
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> Unit
)

jvm

dependencies: kotlin-test-junit5 or kotlin-test-junit4, kotlinx-coroutines-core

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
import kotlin.test.assertTrue
import kotlin.test.fail
actual fun runTest(
expected: ((Throwable) -> Boolean)?,
context: CoroutineContext,
block: suspend CoroutineScope.() -> Unit
) {
var produced: Throwable? = null
try {
runBlocking(context = context, block = block)
} catch (e: Throwable) {
produced = e
}
if (produced != null) {
if (expected != null) {
assertTrue(expected(produced), "Unexpected exception was produced: $produced")
} else {
throw produced
}
} else {
if (expected != null) {
fail("Expected exception was not produced.")
}
}
}

ついでにsuspend functionのexpected exception assertionに対応しています。

assertkでもsuspend functionのテストを簡単に書けるようになるといいなと思います。まだ対応は進んでないようです。