如何使用协程对 Kotlin-JS 代码进行单元测试?
How to unit-test Kotlin-JS code with coroutines?
我创建了一个多平台 Kotlin 项目(JVM 和 JS),声明了预期的 class 并实现了它:
// Common module:
expect class Request(/* ... */) {
suspend fun loadText(): String
}
// JS implementation:
actual class Request actual constructor(/* ... */) {
actual suspend fun loadText(): String = suspendCoroutine { continuation ->
// ...
}
}
现在我正在尝试使用 kotlin.test
进行单元测试,对于 JVM 平台,我只是像这样使用 runBlocking
:
@Test
fun sampleTest() {
val req = Request(/* ... */)
runBlocking { assertEquals( /* ... */ , req.loadText()) }
}
如果没有runBlocking
,如何在JS平台上重现类似的功能?
Mb 已经晚了,但是有开放 issue 可以增加在 js-tests 中使用 suspend
函数的可能性(这个函数将透明地转换为 promise)
解决方法:
可以在普通代码中定义:
expect fun runTest(block: suspend () -> Unit)
在 JVM 中实现
actual fun runTest(block: suspend () -> Unit) = runBlocking { block() }
在 JS 中
actual fun runTest(block: suspend () -> Unit): dynamic = promise { block() }
我能够完成以下工作:
expect fun coTest(timeout: Duration = 30.seconds, block: suspend () -> Unit): Unit
// jvm
actual fun coTest(timeout: Duration, block: suspend () -> Unit) {
runBlocking {
withTimeout(timeout) {
block.invoke()
}
}
}
// js
private val testScope = CoroutineScope(CoroutineName("test-scope"))
actual fun coTest(timeout: Duration, block: suspend () -> Unit): dynamic = testScope.async {
withTimeout(timeout) {
block.invoke()
}
}.asPromise()
这会使用 async
在您选择的范围内启动一个 co-routine,然后您可以像承诺一样 return。
然后你像这样写一个测试:
@Test
fun myTest() = coTest {
...
}
我创建了一个多平台 Kotlin 项目(JVM 和 JS),声明了预期的 class 并实现了它:
// Common module:
expect class Request(/* ... */) {
suspend fun loadText(): String
}
// JS implementation:
actual class Request actual constructor(/* ... */) {
actual suspend fun loadText(): String = suspendCoroutine { continuation ->
// ...
}
}
现在我正在尝试使用 kotlin.test
进行单元测试,对于 JVM 平台,我只是像这样使用 runBlocking
:
@Test
fun sampleTest() {
val req = Request(/* ... */)
runBlocking { assertEquals( /* ... */ , req.loadText()) }
}
如果没有runBlocking
,如何在JS平台上重现类似的功能?
Mb 已经晚了,但是有开放 issue 可以增加在 js-tests 中使用 suspend
函数的可能性(这个函数将透明地转换为 promise)
解决方法:
可以在普通代码中定义:
expect fun runTest(block: suspend () -> Unit)
在 JVM 中实现
actual fun runTest(block: suspend () -> Unit) = runBlocking { block() }
在 JS 中
actual fun runTest(block: suspend () -> Unit): dynamic = promise { block() }
我能够完成以下工作:
expect fun coTest(timeout: Duration = 30.seconds, block: suspend () -> Unit): Unit
// jvm
actual fun coTest(timeout: Duration, block: suspend () -> Unit) {
runBlocking {
withTimeout(timeout) {
block.invoke()
}
}
}
// js
private val testScope = CoroutineScope(CoroutineName("test-scope"))
actual fun coTest(timeout: Duration, block: suspend () -> Unit): dynamic = testScope.async {
withTimeout(timeout) {
block.invoke()
}
}.asPromise()
这会使用 async
在您选择的范围内启动一个 co-routine,然后您可以像承诺一样 return。
然后你像这样写一个测试:
@Test
fun myTest() = coTest {
...
}