https://kotlinlang.org logo
Title
m

Maciek

01/08/2020, 11:58 AM
I'm trying to make tests for rendezvous channels that sends data between two separate coroutines but can't find a proper way to do it. Below is the setup I'm trying to test but this code doesn't work, assert is not executed because coroutine suspends on receive and test finishes
I've tried getting
job
out of first coroutine launch and waiting for it in
runBlocking
but that resulted in blocking the test indefinitely
d

Dominaezzz

01/08/2020, 12:23 PM
@Test
fun `test channels`() = runBlocking {
	val channel = Channel<Int>()
	launch {
		assert(channel.receive() == 1)
	}
	launch {
		delay(1)
		channel.offer(0)
	}
}
👍 2
m

Maciek

01/08/2020, 12:32 PM
Thanks for the reply @Dominaezzz, your test works but that's the problem that I needed those separate scopes, different
MainScope
objects. This is just sample code to simulate architecture that I'm testing. I guess in order to make it testable I have to design code that scope can be injected and replaced in tests
d

Dominaezzz

01/08/2020, 12:45 PM
Ah. and this doesn't work.
@Test
fun `test channels`() {
	val channel = Channel<Int>()
	val job1 = MainScope().launch {
		assert(channel.receive() == 1)
	}
	val job2 = MainScope().launch {
		delay(1)
		channel.offer(0)
	}
    runBlocking { job1.join(); job2.join() }
}
m

Maciek

01/08/2020, 12:48 PM
yup, it hangs forever. Thanks for the idea of using test scope from
runBlocking
, I've changed the architecture to inject it in the objects constructors and everything works. But I wonder if this case with separate scopes is testable at all
d

Dominaezzz

01/08/2020, 12:49 PM
I just realised that
Dispatchers.Main
might not be available in tests. Although I'm not sure if it matters.
m

Maciek

01/08/2020, 12:50 PM
I'm using in the test setup
Dispatchers.setMain(TestCoroutineDispatcher())
so that shouldn't be a problem