Skip to content

Commit 3b78d8a

Browse files
committed
Refactor: Move Turbine test to a separate file
This commit refactors the Flow testing snippets by moving the Turbine test to its own file. To avoid code duplication, the and classes were moved to a new file, so they can be shared between tests.
1 parent 4eb89fd commit 3b78d8a

File tree

4 files changed

+87
-71
lines changed

4 files changed

+87
-71
lines changed

kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,10 @@
1616

1717
package com.android.example.flow.test
1818

19-
import app.cash.turbine.test
20-
import kotlinx.coroutines.ExperimentalCoroutinesApi
2119
import kotlinx.coroutines.flow.Flow
22-
import kotlinx.coroutines.flow.MutableSharedFlow
2320
import kotlinx.coroutines.flow.first
2421
import kotlinx.coroutines.flow.flow
25-
import kotlinx.coroutines.flow.map
2622
import kotlinx.coroutines.flow.toList
27-
import kotlinx.coroutines.launch
28-
import kotlinx.coroutines.test.UnconfinedTestDispatcher
2923
import kotlinx.coroutines.test.runTest
3024
import org.junit.Assert.assertEquals
3125
import org.junit.Test
@@ -91,65 +85,4 @@ class RepositoryTest {
9185
}
9286
}
9387

94-
// [START android_snippets_kotlin_flow_test_repository_and_datasource]
95-
interface DataSource {
96-
fun counts(): Flow<Int>
97-
}
98-
99-
class Repository(private val dataSource: DataSource) {
100-
fun scores(): Flow<Int> {
101-
return dataSource.counts().map { it * 10 }
102-
}
103-
}
104-
105-
class FakeDataSource : DataSource {
106-
private val flow = MutableSharedFlow<Int>()
107-
suspend fun emit(value: Int) = flow.emit(value)
108-
override fun counts(): Flow<Int> = flow
109-
}
110-
// [END android_snippets_kotlin_flow_test_repository_and_datasource]
111-
112-
@OptIn(ExperimentalCoroutinesApi::class)
113-
class ContinuousCollectionTest {
114-
@Test
115-
fun continuouslyCollect() = runTest {
116-
// [START android_snippets_kotlin_flow_test_continuously_collect]
117-
val dataSource = FakeDataSource()
118-
val repository = Repository(dataSource)
11988

120-
val values = mutableListOf<Int>()
121-
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
122-
repository.scores().toList(values)
123-
}
124-
125-
dataSource.emit(1)
126-
assertEquals(10, values[0]) // Assert on the list contents
127-
128-
dataSource.emit(2)
129-
dataSource.emit(3)
130-
assertEquals(30, values[2])
131-
132-
assertEquals(3, values.size) // Assert the number of items collected
133-
// [END android_snippets_kotlin_flow_test_continuously_collect]
134-
}
135-
136-
@Test
137-
fun usingTurbine() = runTest {
138-
// [START android_snippets_kotlin_flow_test_using_turbine]
139-
val dataSource = FakeDataSource()
140-
val repository = Repository(dataSource)
141-
142-
repository.scores().test {
143-
// Make calls that will trigger value changes only within test{}
144-
dataSource.emit(1)
145-
assertEquals(10, awaitItem())
146-
147-
dataSource.emit(2)
148-
awaitItem() // Ignore items if needed, can also use skip(n)
149-
150-
dataSource.emit(3)
151-
assertEquals(30, awaitItem())
152-
}
153-
// [END android_snippets_kotlin_flow_test_using_turbine]
154-
}
155-
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (C) 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.example.flow.test
18+
19+
import app.cash.turbine.test
20+
import kotlinx.coroutines.test.runTest
21+
import org.junit.Assert.assertEquals
22+
import org.junit.Test
23+
24+
class TurbineTest {
25+
@Test
26+
fun usingTurbine() = runTest {
27+
// [START android_snippets_kotlin_flow_test_using_turbine]
28+
val dataSource = FakeDataSource()
29+
val repository = Repository(dataSource)
30+
31+
repository.scores().test {
32+
// Make calls that will trigger value changes only within test{}
33+
dataSource.emit(1)
34+
assertEquals(10, awaitItem())
35+
36+
dataSource.emit(2)
37+
awaitItem() // Ignore items if needed, can also use skip(n)
38+
39+
dataSource.emit(3)
40+
assertEquals(30, awaitItem())
41+
}
42+
// [END android_snippets_kotlin_flow_test_using_turbine]
43+
}
44+
}

kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ class ViewModelTest {
6565
@get:Rule
6666
val mainDispatcherRule = MainDispatcherRule()
6767

68+
// [START android_snippets_kotlin_flow_test_hot_fake_repository]
6869
@Test
6970
fun testHotFakeRepository() = runTest {
70-
// [START android_snippets_kotlin_flow_test_hot_fake_repository]
7171
val fakeRepository = FakeRepository()
7272
val viewModel = MyViewModel(fakeRepository)
7373

@@ -83,8 +83,8 @@ class ViewModelTest {
8383
fakeRepository.emit(2)
8484
fakeRepository.emit(3)
8585
assertEquals(3, viewModel.score.value) // Assert on the latest value
86-
// [END android_snippets_kotlin_flow_test_hot_fake_repository]
8786
}
87+
// [END android_snippets_kotlin_flow_test_hot_fake_repository]
8888
}
8989

9090
// [START android_snippets_kotlin_flow_test_my_view_model_with_state_in]
@@ -101,9 +101,9 @@ class LazilySharingViewModelTest {
101101
@get:Rule
102102
val mainDispatcherRule = MainDispatcherRule()
103103

104+
// [START android_snippets_kotlin_flow_test_lazily_sharing_view_model]
104105
@Test
105106
fun testLazilySharingViewModel() = runTest {
106-
// [START android_snippets_kotlin_flow_test_lazily_sharing_view_model]
107107
val fakeRepository = HotFakeRepository()
108108
val viewModel = MyViewModelWithStateIn(fakeRepository)
109109

@@ -121,6 +121,6 @@ class LazilySharingViewModelTest {
121121
fakeRepository.emit(2)
122122
fakeRepository.emit(3)
123123
assertEquals(3, viewModel.score.value)
124-
// [END android_snippets_kotlin_flow_test_lazily_sharing_view_model]
125124
}
125+
// [END android_snippets_kotlin_flow_test_lazily_sharing_view_model]
126126
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (C) 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.example.flow.test
18+
19+
import kotlinx.coroutines.flow.Flow
20+
import kotlinx.coroutines.flow.MutableSharedFlow
21+
import kotlinx.coroutines.flow.map
22+
23+
// [START android_snippets_kotlin_flow_test_repository_and_datasource]
24+
interface DataSource {
25+
fun counts(): Flow<Int>
26+
}
27+
28+
class Repository(private val dataSource: DataSource) {
29+
fun scores(): Flow<Int> {
30+
return dataSource.counts().map { it * 10 }
31+
}
32+
}
33+
34+
class FakeDataSource : DataSource {
35+
private val flow = MutableSharedFlow<Int>()
36+
suspend fun emit(value: Int) = flow.emit(value)
37+
override fun counts(): Flow<Int> = flow
38+
}
39+
// [END android_snippets_kotlin_flow_test_repository_and_datasource]

0 commit comments

Comments
 (0)