代码之家  ›  专栏  ›  技术社区  ›  egor.zhdan

如何使用协同程序对Kotlin JS代码进行单元测试?

  •  9
  • egor.zhdan  · 技术社区  · 7 年前

    我创建了一个多平台Kotlin项目(JVM&JS),声明了一个预期的类并实现了它:

    // 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()) }
    }
    

    如果JS平台上没有 运行阻塞 ?

    2 回复  |  直到 4 年前
        1
  •  5
  •   kurt    7 年前

    Mb很晚了,但还有空位 issue 增加使用可能性 suspend js测试中的函数(在那里,此函数将透明转换为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() } 
    
        2
  •  0
  •   Jilles van Gurp    3 年前

    我能够完成以下工作:

    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()
    

    这将在您选择的范围内启动一个co例程,使用 async 然后你可以像承诺一样回来。

    然后编写如下测试:

    @Test
    fun myTest() = coTest {
      ...
    }