如何使用Spock(Groovy)测试Kotlin挂起功能

yebdmbv4  于 2022-09-21  发布在  Kotlin
关注(0)|答案(3)|浏览(201)

我有以下Kotlin暂停功能:

suspend fun registerNewTransaction(transaction: String): String

我试图通过Spock测试它,但我还没有找到在不指定Continuation<? super String>参数的情况下调用这个Kotlin挂起函数的方法,因为Groovy将Kotlin容器类标识为Java类。我想知道是否有可能从另一种基于JVM的语言调用挂起的函数,否则我将不得不使用另一个测试库,如JUnit。

h79rfbju

h79rfbju1#

您可以模拟延续对象,Kotlin正在将其编译到方法调用中。这段代码对我很有效:

// mocked continuation
def continuation = Mock(Continuation) {
  getContext() >> Mock(CoroutineContext)
}

// method call which should be tested
subjectUnderTest.suspendableMethod(someParameter, continuation)
htrmnn0y

htrmnn0y2#

@julianwki的答案会在运行类似于:withContext(Dispatchers.IO) { /* ... /*/ }的命令后中断

更强大的版本是使用实际的CoroutineContext运行,而不是嘲笑它:

def continuation = Mock(Continuation) {
    getContext() >> Dispatchers.Default
}

我假设可以通过调用TestScopeKt.TestScope(EmptyCoroutineContext.INSTANCE)(org.jetbrains.kotlinx:kotlinx-coroutines-test)来创建Continuation,因为这似乎是底层runTest所使用的。然而,我最近找到了一个很好的方法来达到这一点。

还要注意,模拟Continuation我们没有fun resumeWith(result: Result<T>)的实现,这到目前为止似乎不是问题,但可能会在未来成为问题。找到一个完全不受嘲弄的解决方案可能是可取的。

此外,如果从Groovy/Spock调用挂起函数,可能就不走运了。我确实尝试了上建议的解决方案:Call Kotlin suspend function in Java class和类似的“hack”,如果直接从Groovy调用它们的话。人们也许能够为所需的每个调用创建一个Kotlin Package ,然而,至少在我的例子中是不可行的

zqdjd7g9

zqdjd7g93#

如果可以从另一种基于JVM的语言调用挂起函数

这是可能的,但您需要将Continuation作为最后一个参数传递,因为这是Kotlin编译suspend函数的方式

我建议使用Kotlin来测试Kotlin代码,有很多特定于Kotlin的库,如mockk,它们支持协程。

相关问题