InsertKoinIO / koin

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

Provide a way to load modules immediatly for Android instrumented tests #1318

Closed christophehenry closed 2 years ago

christophehenry commented 2 years ago

Is your feature request related to a problem? Please describe. As the documentation states, on Android, Koin is started by the Application class which means that loaded modules are the same for every instrumentation tests.

The documentation states that "loadModules and unloadModules are often unsafe because the changes are not applied immediately" which means that modules can't reliebly be swapped — for instance by a mock — for the course of one or a series of specific tests.

It is not clear here if createEagerInstances() and singles createdAtStart parameter provide a partial solution to that problem by always immediatly creating singleton modules.

Describe the solution you'd like loadModules and unloadModules could provide a executeImmediatly for swapping modules with immediate exectution.

Target Koin project Koin

gmk57 commented 2 years ago

Yes, we're looking for it too!

The topic of proper Koin setup for instrumented tests is discussed for almost two years, but sill lacks a perfect solution.

Part of the problem is probably the vague documentation: "recommended approach is to add a module of your overrides to modules used by startKoin in the application's Application class".

Where should we do that?

Adding instrumentedTestModule in production Application is neither possible nor desirable. Docs probably mean using a special Application class for tests via manifest or test runner, but this is not said clearly.

I find it strange compared to very clear & practical Koin documentation in general (yes, we're looking at you, Dagger ;)).

christophehenry commented 2 years ago

Docs probably mean using a special Application class for tests via manifest or test runner, but this is not said clearly.

I think docs mean via test runner, which is what I use. The first problem is this solution seems not described anywhere in Android's documentation (I found my answer on StackOverflow). The second is there is no way to load different modules for different tests. The runner and thus the Application is the same for all the instrumented tests. You can't isolate one module for one test, for instance, in order to mock it.

Currently, for me, singleton module seem to escape this problem since you can create them eagerly and, looking at the code, they are always loaded as soon as you call loadModules when creating them eagerly. So you can call loadModules in @Before functions reliably. But this is not official.

arnaudgiuliani commented 2 years ago

Yes, should have more precise point on it

arnaudgiuliani commented 2 years ago

Please follow updated doc introduced in https://github.com/InsertKoinIO/koin/pull/1409