I have a function that collects a flow and does other operations through launching other coroutines, in my tests for that function it looks like none of my coroutines launches. is there something I am missing here?
class Tax(
private val coroutineScope: CoroutineScope,
) {
fun operate() {
coroutineScope.launch {
// some work done here
}
}
}
// My Test class
@Test
fun `test operate`() = runTest {
val tax = Tax(this)
tax.operate()
// verify something with in the coroutineScope.launch always fails
}
You either need to wait till testScheduler schedules coroutine by calling advanceUntilIdle, calling coroutineScope or use UnconfinedTestDispatcher as coroutineContext with new TestScope as
class SampleTest {
private val coroutineScope = TestScope()
// My Test class
@Test
fun `test operate`() = coroutineScope.runTest {
val tax = Tax(coroutineScope)
tax.operate()
advanceUntilIdle()
// verify something with in the coroutineScope.launch always fails
}
}
or use UnconfinedTestDispatcher as
class SampleTest {
private val coroutineScope = TestScope(UnconfinedTestDispatcher())
// My Test class
@Test
fun `test operate`() = coroutineScope.runTest {
val tax = Tax(coroutineScope)
tax.operate()
advanceUntilIdle()
// verify something with in the coroutineScope.launch always fails
}
}
You can check out these samples i did based Android Coroutine Test document
class UserRepository {
private val users = mutableListOf<String>()
fun registerUsers(user: String) {
users.add(user)
}
suspend fun registerUserAsync(user: String) {
delay(100)
users.add(user)
}
fun getAllUsers(): MutableList<String> {
return users
}
}
And tests
join
@Test
fun standardTestWithJoin() = runTest {
val userRepo = UserRepository()
val job1 = launch { userRepo.registerUsers("Alice") }
val job2 = launch { userRepo.registerUsers("Bob") }
job1.join()
job2.join()
assertEquals(listOf("Alice", "Bob"), userRepo.getAllUsers()) // ✅ Passes
}
advanceTillIdle
// 🔥 This test passes with registerUserAsync too
@Test
fun standardTest2() = runTest {
val userRepo = UserRepository()
launch { userRepo.registerUsers("Alice") }
launch { userRepo.registerUsers("Bob") }
advanceUntilIdle() // Yields to perform the registrations
assertEquals(listOf("Alice", "Bob"), userRepo.getAllUsers()) // ✅ Passes
}
UnconfinedTestDispatcher
// 🔥 This test fails with registerUserAsync(delay)
@Test
fun unconfinedTest() = runTest(UnconfinedTestDispatcher()) {
val userRepo = UserRepository()
launch { userRepo.registerUsers("Alice") }
launch { userRepo.registerUsers("Bob") }
assertEquals(listOf("Alice", "Bob"), userRepo.getAllUsers()) // ✅ Passes
}
@Test
fun unconfinedTest2() = runTest(UnconfinedTestDispatcher()) {
val userRepo = UserRepository()
launch { userRepo.registerUserAsync("Alice") }
launch { userRepo.registerUserAsync("Bob") }
// 🔥 Need to call for past to test
advanceUntilIdle()
assertEquals(listOf("Alice", "Bob"), userRepo.getAllUsers()) // ✅ Passes
}
https://developer.android.com/kotlin/coroutines/test#standardtestdispatcher
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With