InsertKoinIO / koin

Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
https://insert-koin.io
Apache License 2.0
8.77k stars 695 forks source link

[koin-android-compose] Broken view model factory when migrating from 3.5.0 -> 3.5.3/3.5.4 #1844

Open javiercamarenatriguero opened 2 months ago

javiercamarenatriguero commented 2 months ago

Describe the bug I recently upgraded to koin-androidx-compose:3.5.4 from koin-androidx-compose:3.5.0 and the Automation Test stat failing because of this error:

Caused by: org.koin.core.error.ClosedScopeException: Scope '_root_' is closed
        at org.koin.core.scope.Scope.resolveInstance(Scope.kt:224)
        at org.koin.core.scope.Scope.get(Scope.kt:213)
        at org.koin.androidx.viewmodel.factory.KoinViewModelFactory.create(KoinViewModelFactory.kt:25)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:184)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:150)
        at org.koin.androidx.viewmodel.GetViewModelKt.resolveViewModel(GetViewModel.kt:44)

Tested it just affect to koin-android-compose library as the rest of koin libraries are not affecting the Android Test results. To Reproduce Steps to reproduce the behavior:

  1. Run Automation Test with more than 1 test cases
  2. See error after the second TestCase starts the execution.

Expected behavior It should not fail as v3.5.0 version.

Koin module and version: koin-androidx-compose:3.5.3 & koin-androidx-compose:3.5.4

arnaudgiuliani commented 2 months ago

Can you detail it a bit more?

javiercamarenatriguero commented 2 months ago

Thanks @arnaudgiuliani ! Sure, The issue just affects when the koin-androidx-compose is upgraded from v3.5.0 -> v3.5.3/4. The code contains some Automation Test in Espresso, and for some reason the second Test Case of the same Test Class fails when the ViewModelFactory tries to get the instance of the ViewModel. In order to provide more information, this is the KoinTestRule used on the Test Class (based on tutorials):

class KoinTestRule(
    private val modules: List<Module> = emptyList()
) : TestWatcher() {

    private val modulesByDefault = listOf(dataModule, useCaseModule, viewModelModule, appModule)
    override fun starting(description: Description) {
        startKoin {
            androidContext(InstrumentationRegistry.getInstrumentation().targetContext.applicationContext)
            modules(modulesByDefault + modules)
        }
    }

    override fun finished(description: Description) {
        stopKoin()
    }
}

And this is the invocation on the Test Class:

private val instrumentedTestModule = module {
        factory { getMockDataLocalSource() }
        factory { getMockQuestions(questionJson) }
        ...
    }

    override val koinTestRule: KoinTestRule
        get() = KoinTestRule(
            modules = listOf(instrumentedTestModule)
        )

The first TestCase works fine, but the second one fails on this. It happens to all the Test Classes. It was working fine until now. Thanks in advance

kasim-canol-sz commented 2 months ago

@arnaudgiuliani Do you have any updates regarding this issue? Our tests are also affected by the same issue, therefore we're currently not able to update the koin version.

javiercamarenatriguero commented 2 months ago

Hi @arnaudgiuliani, any update about this issue? Thanks in advance

arnaudgiuliani commented 1 month ago

weird, seems that VM factory is invoked after scope closing 🤔

arnaudgiuliani commented 1 month ago

can anyone help by providing a test project for that? @kasim-canol-sz @javiercamarenatriguero