Search code examples
testingreflectionqualifierskoinwhite-box

No definition found for qualifier: How to solve Kotlin reflection is not available when creating modules with Koin test?


I'm trying to create a simple white-box test with Koin. After setting qualifier to pass a mock as parameter to an instance (or supposedly what I want to do) I'm receiving an error which says:

org.koin.core.error.NoBeanDefFoundException: No definition found for qualifier='null' & class='class com.imagebucket.main.repository.GalleryRepositoryImpl (Kotlin reflection is not available)'

Test

class GalleryRepositoryTest: AutoCloseKoinTest() {

    private val module = module {
        named("repository").apply {
            single<GalleryRepository>(this) { GalleryRepositoryImpl() }
            single { GalleryViewModel(get(this.javaClass)) }
        }
    }

    private val repository: GalleryRepositoryImpl by inject()
    private val vm: GalleryViewModel by inject()

    @Before
    fun setup() {
        startKoin { loadKoinModules(module) }
        declareMock<GalleryRepositoryImpl>()
    }

    @Test
    fun uploadImage_withEmptyUri_shouldDoNothing() {
        vm.delete("")
        verify(repository).delete("")
    }
}

ViewModel

class GalleryViewModel(private val repository: GalleryRepository) : ViewModel() {

    fun delete(name: String) {
        repository.delete(name)
    }
}

I also tried a similar approach with Robolectric runner, but after creating the module in Application file, my mock wouldn't be invoked using verify(repository).delete("").

How can I manage to solve this problem and move forward with this simple test?


Solution

  • As noticed by Arnaud at Koin's repository, issue #584, there should have a code replacement

    from:

    private val module = module {
        single<GalleryRepository>(named("repository")) {
            GalleryRepositoryImpl() 
        }
    
        viewModel { GalleryViewModel(get()) }
    }
    
    private val repository: GalleryRepositoryImpl by inject()
    
    private val vm: GalleryViewModel by inject(named("repository"))
    

    to:

    private val module = module {
        single<GalleryRepository>(named("repository")) { 
            GalleryRepositoryImpl() 
        }
    
        viewModel { GalleryViewModel(get(named("repository"))) }
    }
    
    private val repository: GalleryRepository by inject(named("repository"))
    
    private val vm: GalleryViewModel by inject()