Skip to content

[question] Is this "IllegalStateException: This job has not completed yet" while using runBlockingTest normal? #1222

Closed
@sum-elier

Description

@sum-elier

Why when executing the following test:

@Test
fun foo() = runBlockingTest {
  bar()
}

suspend fun bar() {
  println(1)
  withContext(Dispatchers.IO) {
	 println(2)
  }
  println(3)
}

The output is:

1
2
3

java.lang.IllegalStateException: This job has not completed yet

	at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1114)
	at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53)
	at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)
	at com.foopkg.MyTests.foo(MyTests.kt:11)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1251)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1251)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Is it related to #1204 ?

Activity

changed the title [-][question] Is this "IllegalStateException: This job has not completed yet" normal?[/-] [+][question] Is this "IllegalStateException: This job has not completed yet" while using runBlockingTest normal?[/+] on May 26, 2019
voghDev

voghDev commented on May 27, 2019

@voghDev

I'm having the same problem. I'll paste the Test I'm running here, for if it helps

Test (NewsPresenterTest.kt)

@Test
fun `should load first page of news on start`() = runBlockingTest {
    givenThereAreNoNews()

    presenter.initialize()

    verify(mockNewsRepository).getNews(eq(1), anyLong())
}

Production code (NewsPresenter.kt)

override suspend fun initialize() {
    val result = coroutine { newsRepository.getNews(page) }

    // do more stuff with the result...
}

suspend fun <T> coroutine(
    context: CoroutineContext = Dispatchers.IO,
    block: suspend CoroutineScope.() -> T
): T = withContext(context, block)

Expected: Green, run successfully
Output: java.lang.IllegalStateException: This job has not completed yet

[Update] I've noticed that replacing Dispatchers.IO with Dispatchers.Main makes the Test go green. It only fails when using Dispatchers.IO Context

I'm sorry I can't post it to a public GitHub repository :-( I can post any additional code that might be necessary for diagnosing this

elizarov

elizarov commented on May 27, 2019

@elizarov
Contributor
objcode

objcode commented on May 27, 2019

@objcode
Contributor

Thanks for the minimal repro!

In the current version there's an issue that causes runBlockingTest to throw this exception incorrectly when there are multiple threads. This is the same issue reported in #1204

Patch #1206 will change this to pass as expected.

self-assigned this
on May 27, 2019
mkobit

mkobit commented on Aug 19, 2019

@mkobit
Contributor

Been running this with ktor-client tests as well - is the best workaround for now to just use runBlocking (if you don't entirely need all the APIs and support from runBlockingTest)?

LypchenkoS

LypchenkoS commented on Sep 6, 2019

@LypchenkoS

I replaced runBlockingTest on runBlocking and it helped.

fireb86

fireb86 commented on Sep 10, 2019

@fireb86

I replaced runBlockingTest on runBlocking and it helped.

runBlocking works for me too

private val testDispatcher = TestCoroutineDispatcher()

@Before
fun setup() {
	Dispatchers.setMain(testDispatcher)
}

@After
fun cleanUp() {
	Dispatchers.resetMain()
	testDispatcher.cleanupTestCoroutines()
}

@Test
fun testCoroutines1() = runBlocking {
	withContext(Dispatchers.Main) {
		Assert.assertEquals(job1().await() and job2().await(), false)
	}
}

@Test
fun testCoroutines2() = runBlocking {
	withContext(Dispatchers.Main) {
		Assert.assertEquals(job1().await() or job2().await(), true)
	}
}

suspend fun job1() = GlobalScope.async(Dispatchers.Default) {
	delay(1000)
	true
}

suspend fun job2() = GlobalScope.async(Dispatchers.Default) {
	delay(500)
	false
}
glasser

glasser commented on Sep 10, 2019

@glasser
Contributor

The one annoying thing about runBlocking is that JUnit tests don't run unless they return Unit, but it's hard to remember to always type runBlocking<Unit> or fun testFoo(): Unit = runBlocking`.

We use this just to get around that:

fun testBlocking(test: suspend CoroutineScope.() -> Unit) = runBlocking { test() }
leandrofnjr

leandrofnjr commented on Jan 22, 2020

@leandrofnjr

Hi,

i'm facing same issue as described above executing my room database unit tests.

Has there been found out any fix for that ?

nuhkoca

nuhkoca commented on Feb 18, 2020

@nuhkoca

Still continuing. I am using a custom CoroutinesTestRule but still getting this issue. Any workaround except using runBlocking?

added a commit that references this issue on Mar 3, 2020

42 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @glasser@twyatt@objcode@elizarov@mkobit

      Issue actions

        [question] Is this "IllegalStateException: This job has not completed yet" while using runBlockingTest normal? · Issue #1222 · Kotlin/kotlinx.coroutines