`suspendCoroutine` 抛出`这个作业尚未完成` 异常?

Yek*_*ğlu 5 android kotlin android-testing kotlin-coroutines google-mlkit

我正在尝试测试我的封装翻译器类,该类在底层使用Google ML Kit Translate 。我收到一个错误,抛出java.lang.IllegalStateException: This job has not completed yet. 我不太明白为什么会出现这个异常。有人有想法吗?

\n
import com.google.common.truth.Truth.assertThat\nimport kotlinx.coroutines.CoroutineDispatcher\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.runBlocking\nimport kotlinx.coroutines.test.TestCoroutineDispatcher\nimport kotlinx.coroutines.test.resetMain\nimport kotlinx.coroutines.test.runBlockingTest\nimport kotlinx.coroutines.test.setMain\nimport org.junit.Before\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.rules.TestWatcher\nimport org.junit.runner.Description\nimport timber.log.Timber\nimport kotlin.coroutines.resume\nimport kotlin.coroutines.suspendCoroutine\n\nclass GoogleMLKitTranslatorTest {\n\n    private lateinit var translator: GoogleMLKitTranslator\n\n    private val testValue = "Bana herhangi bir \xc5\x9fey sor"\n\n    @get:Rule\n    var coroutinesTestRule = CoroutineTestRule()\n\n    @Before\n    fun setup() {\n        translator = GoogleMLKitTranslator()\n        translator.initialize()\n\n        Timber.plant(Timber.DebugTree())\n    }\n\n    @Test\n    fun translate_turkish_test_to_english_should_return_true() =\n        coroutinesTestRule.testDispatcher.runBlockingTest {\n            val expectedValue = "Ask me anything"\n\n            val translatedText = suspendCoroutine<String> { continuation ->\n                translator.translate(\n                    value = testValue,\n                    onSuccess = {\n                        continuation.resume(it)\n                    },\n                    onFailure = {\n                        continuation.resume(it.message ?: "Wow, something is wrong!")\n                    }\n                )\n            }\n\n            Timber.d("Translated text is $translatedText")\n            assertThat(translatedText).matches(expectedValue)\n        }\n\n    @ExperimentalCoroutinesApi\n    class CoroutineTestRule(val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) : TestWatcher() {\n\n        override fun starting(description: Description?) {\n            super.starting(description)\n            Dispatchers.setMain(testDispatcher)\n        }\n\n        override fun finished(description: Description?) {\n            super.finished(description)\n            Dispatchers.resetMain()\n            testDispatcher.cleanupTestCoroutines()\n        }\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n
java.lang.IllegalStateException: This job has not completed yet\n    at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1128)\n    at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53)\n    at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:80)\n    at com.theteampotato.gifit.translate.GoogleMLKitTranslatorTest.translate_turkish_test_to_english_should_return_true(GoogleMLKitTranslatorTest.kt:46)\n    at java.lang.reflect.Method.invoke(Native Method)\n    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)\n    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\n    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)\n    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)\n    at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)\n    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)\n    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\n    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)\n    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)\n    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)\n    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)\n    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)\n    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)\n    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)\n    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)\n    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)\n    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\n    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)\n    at org.junit.runners.Suite.runChild(Suite.java:128)\n    at org.junit.runners.Suite.runChild(Suite.java:27)\n    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)\n    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)\n    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)\n    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)\n    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)\n    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\n    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)\n    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)\n    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)\n    at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)\n    at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)\n    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2258)\n
Run Code Online (Sandbox Code Playgroud)\n

Yek*_*ğlu 3

使用runBlocking()而不是以coroutinesTestRule.testDispatcher.runBlockingTest()某种方式解决了问题。任何能够透露一些有用见解的人都非常受欢迎。

  • 我无法提供任何进一步的见解,但协程存储库上有一个未解决的问题,其中包含更多信息 https://github.com/Kotlin/kotlinx.coroutines/issues/1204 (2认同)