Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Koin: NoBeanDefFoundException, Check your module definitions

The koin test results as follows:

org.koin.core.error.NoBeanDefFoundException: No definition found for '<class_name>' has been found. Check your module definitions.

the class EmailValidatorUtilImpl is well implemented,

import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.dsl.module
import org.koin.test.KoinTest
import org.koin.test.inject

class EmailValidatorUtilImpl : EmailValidatorUtil {

    private val pattern = Pattern.compile(EMAIL_PATTERN)
    private var matcher: Matcher? = null

    override fun validateEmail(email: String): Boolean {
        matcher = pattern.matcher(email)
        return matcher!!.matches()
    }

    companion object {
        private val EMAIL_PATTERN = "^[a-zA-Z0-9#_~!$&'()*+,;=:.\"(),:;<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$"
    }
}

and also, injected in KoinTest as below:


class EmailValidatorUtilImplTest : KoinTest, KoinComponent {

    private val validatorUtilImpl: EmailValidatorUtilImpl by inject()

    @Before
    fun setUp() {
        startKoin { module { single { EmailValidatorUtilImpl } } }
    }

    @Test
    fun `is valid email returns true`() {
        val isEmailValid = validatorUtilImpl.validateEmail("[email protected]")
        Assert.assertTrue(isEmailValid)
    }

    @Test
    fun `is invalid email returns false`() {
        val isEmailValid = validatorUtilImpl.validateEmail("invalid_email")
        Assert.assertFalse(isEmailValid)
    }

    @After
    fun tearDown() {
        stopKoin()
    }
}

furthermore, the implementation class is been well injected as


var loginUtilsModule = module {
    single { EmailValidatorUtilImpl() }
}

in Application class:

startKoin {
            androidLogger(Level.DEBUG)
            androidContext(this@SampleApplication)
            modules(listOf(
                    loginUtilsModule
            ))
        }

dependencies (app/build.gradle):


    // di
    implementation 'org.koin:koin-androidx-viewmodel:2.0.1'
    implementation 'org.koin:koin-androidx-scope:2.0.1'
    implementation 'org.koin:koin-android:2.0.1'

    // test
    testImplementation 'org.mockito:mockito-core:2.28.2'
    testImplementation 'org.koin:koin-test:2.0.1'
    testImplementation 'junit:junit:4.12'

    // android test
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'org.koin:koin-test:2.0.1'
like image 864
Faisal Avatar asked Aug 17 '19 11:08

Faisal


3 Answers

I had the same problem, but in my case Koin was unable to resolve an implementation of interface. I had:

interface MessagesRepository {...}

class MessagesRepositoryImpl : MessagesRepository {...}

class GetMessagesUseCase(private val messagesRepository: MessagesRepository) {...}

And in Koin module I wrote:

single { MessagesRepositoryImpl() }
single { GetMessagesUseCase(get()) }

So Koin couldn't find an instance of MessagesRepository to inject it into GetMessagesUseCase. Specifying singleton's type explicitly resolved the issue (but maybe there is a better solution):

single<MessagesRepository> { MessagesRepositoryImpl() }
single { GetMessagesUseCase(get()) }
like image 65
Yamashiro Rion Avatar answered Nov 07 '22 18:11

Yamashiro Rion


I found the issue and the mistake was the module instead of modules (or.koin.core.KoinApplication)

    @Before
    fun setUp() {
        startKoin { module { single { EmailValidatorUtilImpl } } }
    }

so, the solution and the correct version are:

    startKoin { modules(loginUtilsModule) }
like image 42
Faisal Avatar answered Nov 07 '22 18:11

Faisal


 single { MessagesRepositoryImpl() as MessagesRepository }

Yamashiro Rion you can do this

like image 25
bigmeco Avatar answered Nov 07 '22 18:11

bigmeco