Unit test with Kotlin Channel

Viewed 540

I started learning how to use Channel but I'm having problems with the unit tests. For example with the class

class TestOp (private val channel: Channel<String>) {
    suspend fun op() {
        channel.send("new")
    }
}

and to test it

@ExtendWith(CoroutineExecutorExtension::class)
@RunWith(JUnitPlatform::class)
internal class TestOpTest{

    @Test
    fun testOpReturnNew() {
        runBlockingTest {
           val channel = Channel<String>()
           val test = TestOp(channel = channel)
           test.op()
           assertEquals("new", channel.receive())
        }
    }
}

where:

@ExperimentalCoroutinesApi
class CoroutineExecutorExtension : InstantExecutorExtension() {

    private val testCoroutineDispatcher = TestCoroutineDispatcher()

    override fun beforeEach(context: ExtensionContext?) {
        super.beforeEach(context)
        Dispatchers.setMain(testCoroutineDispatcher)
    }

    override fun afterEach(context: ExtensionContext?) {
        super.afterEach(context)
        Dispatchers.resetMain()
        testCoroutineDispatcher.cleanupTestCoroutines()
    }
}

@ExperimentalCoroutinesApi
open class InstantExecutorExtension : BeforeEachCallback, AfterEachCallback {

    override fun beforeEach(context: ExtensionContext?) {
        ArchTaskExecutor.getInstance()
            .setDelegate(object : TaskExecutor() {
                override fun executeOnDiskIO(runnable: Runnable) = runnable.run()

                override fun postToMainThread(runnable: Runnable) = runnable.run()

                override fun isMainThread(): Boolean = true
            })
    }

    override fun afterEach(context: ExtensionContext?) {
        ArchTaskExecutor.getInstance().setDelegate(null)
    }
}


I get the error:

This job has not completed yet java.lang.IllegalStateException: This job has not completed yet at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1190) at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53) at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)

If I use runBlocking the test never completes.

What's the right way to test it?

1 Answers

I fixed the problem adding:

@AfterEach
fun tearDown() {
   viewModel.viewModelScope.cancel()
}

in this way all the coroutines are cancelled and the issue is fixed

Related