Skip to content

Instantly share code, notes, and snippets.

@atsuko-fukui
Created July 21, 2020 10:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atsuko-fukui/4cb826482f3d03d5c37b80e2f71aded1 to your computer and use it in GitHub Desktop.
Save atsuko-fukui/4cb826482f3d03d5c37b80e2f71aded1 to your computer and use it in GitHub Desktop.
Example of Kotlin Coroutine Flow with multiple subscribers
package com.example.atsukofukui.fooexample
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Test
import org.junit.Before
class ExampleUnitTest {
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
private val testScope = TestCoroutineScope()
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
private val dispatcher = TestCoroutineDispatcher()
private lateinit var fooService: FooService
@Before
fun setup() {
fooService = FooService(dispatcher)
}
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
@Test
fun `requestFoo() should trigger getting foo and fooFlow emit foo`() {
testScope.runBlockingTest {
val foo = mutableListOf<String>()
val job = launch {
fooService.fooFlow.collect { foo.add(it) }
}
// ここではまだfooは空
assertThat(foo).isEmpty()
fooService.requestFoo()
assertThat(foo).isEqualTo(listOf("result"))
job.cancel()
}
}
}
class FooService(private val dispatcher: CoroutineDispatcher = Dispatchers.IO) {
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
private val fooChannel = ConflatedBroadcastChannel<Unit>()
@OptIn(
kotlinx.coroutines.FlowPreview::class,
kotlinx.coroutines.ExperimentalCoroutinesApi::class
)
val fooFlow = fooChannel.asFlow().map { getFooFromRemoteSource() }.flowOn(dispatcher)
private fun getFooFromRemoteSource(): String {
val result = "result"
return result
}
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
fun requestFoo() {
fooChannel.offer(Unit)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment