Zach Olbrys
02/05/2024, 10:14 PMDispatchers.resetMain
after tests in module 1 it can affect tests in module 2, 3, ... x since it's using a singleton to control the main dispatcher and the tests for each module can run at the same time….kevin.cianfarini
02/05/2024, 10:19 PMDispatchers.setMain
and Dispatchers.resetMain
. You should instead consider injecting your dispatchers to your code under test so that you can control dispatchers locally within a test, not globally.Zach Olbrys
02/05/2024, 10:24 PMkevin.cianfarini
02/05/2024, 10:26 PMviewModelScope
is now discouraged by google because of its static dependency on Dispatchers.Main
.Zach Olbrys
02/06/2024, 1:54 AMviewModelScope
? That seems to be the biggest question mark for this. I've got dispatchers being injected everywhere else as far as I can tell in my code/libraries, so I can control those no problemIan Lake
02/06/2024, 4:09 AMZach Olbrys
02/06/2024, 4:11 AMZach Olbrys
02/06/2024, 9:58 PMkevin.cianfarini
02/06/2024, 9:59 PMZach Olbrys
02/06/2024, 11:49 PMcachedIn
API causes some issues and requires the coroutine test rule to function.
I can't see why though.
I created a paging issue to track this: we'll see... https://issuetracker.google.com/issues/324108012
Maybe I am doing something wrong - (hopefully!)CLOVIS
02/07/2024, 9:51 AMZach Olbrys
02/07/2024, 12:26 PMAbhimanyu
05/09/2024, 2:18 PMviewModelScope
.
https://developer.android.com/jetpack/androidx/releases/lifecycle#2.5.0
Does this create additional Job()
?
class CloseableCoroutineScope(
context: CoroutineContext = SupervisorJob() + Dispatchers.Main.immediate
) : Closeable, CoroutineScope {
override val coroutineContext: CoroutineContext = context
override fun close() {
coroutineContext.cancel()
}
}
kevin.cianfarini
05/09/2024, 2:19 PMCloseableCoroutineScope
at call site. If you pass in nothing, the default will be to create a new supervisor job.Abhimanyu
05/09/2024, 2:24 PMCloseableCoroutineScope
public class CloseableCoroutineScope(
private val dispatcherProvider: DispatcherProvider,
context: CoroutineContext = SupervisorJob() + dispatcherProvider.mainImmediate,
) : Closeable, CoroutineScope {
override val coroutineContext: CoroutineContext = context
override fun close() {
coroutineContext.cancel()
}
}
CloseableCoroutineScopeModule
@Module
@InstallIn(SingletonComponent::class)
public object CloseableCoroutineScopeModule {
@Provides
public fun providesCloseableCoroutineScope(
dispatcherProvider: DispatcherProvider,
): CloseableCoroutineScope {
return CloseableCoroutineScope(
dispatcherProvider = dispatcherProvider,
)
}
}
ViewModel
@HiltViewModel
internal class SettingsScreenViewModel @Inject constructor(
private val closeableCoroutineScope: CloseableCoroutineScope,
) : ViewModel(closeableCoroutineScope) {
Ian Lake
05/09/2024, 5:17 PMviewModelScope
is a constructor parameter directly: https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.0-alpha03Abhimanyu
05/09/2024, 6:23 PMclass MyViewModel(
// Make Dispatchers.Main the default, rather than Dispatchers.Main.immediate
viewModelScope: CoroutineScope = Dispatchers.Main + SupervisorJob()
) : ViewModel(viewModelScope) {
// Use viewModelScope as before, without any code changes
}
Is this SupervisorJob()
recommended to be used or we can avoid that?
Can you please share a bit more on that?
Thank You.Ian Lake
05/09/2024, 7:11 PM