Koin: NoBeanDefFoundException, 检查您的模块定义

12

koin测试结果如下:

org.koin.core.error.NoBeanDefFoundException: 未找到“<class_name>”的定义。请检查您的模块定义。

EmailValidatorUtilImpl已经很好地实现了。

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-]+)*$"
    }
}

同时,如下所示将其注入到KoinTest中:


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("someone@somewhere.com")
        Assert.assertTrue(isEmailValid)
    }

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

    @After
    fun tearDown() {
        stopKoin()
    }
}
此处应该翻译为:此外,实现类已被良好注入。

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

在 Application 类中:

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

依赖关系(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'

你尝试过将 KoinComponent 移除,只保留测试中的 KoinTest 吗? - Napster
是的,我尝试过了。KoinComponent 不是故意的。 - Faisal
你能否在测试文件中添加导入并在Gradle中测试依赖项? - Napster
@Napster 在问题中进行了更新。 - Faisal
3个回答

26

我遇到了同样的问题,但是在我的情况下,Koin无法解析接口的实现。我的情况如下:

interface MessagesRepository {...}

class MessagesRepositoryImpl : MessagesRepository {...}

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

而在我的 Koin 模块中,我编写了以下内容:

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

因此,Koin找不到MessagesRepository实例以将其注入GetMessagesUseCase中。 显式指定单例类型解决了该问题(但也许有更好的解决方案):

single<MessagesRepository> { MessagesRepositoryImpl() }
single { GetMessagesUseCase(get()) }

这是我的问题,只不过我在另一个模块中解决了依赖关系。很奇怪。 - Aerim
这对我来说也是如此,谢谢。 - FabioR

18
我找到了问题,错误发生在模块而不是模块 (or.koin.core.KoinApplication)
    @Before
    fun setUp() {
        startKoin { module { single { EmailValidatorUtilImpl } } }
    }

所以,解决方案和正确版本为:

    startKoin { modules(loginUtilsModule) }

救了我的一天,我在ViewModel上也遇到了同样的问题,感谢你找到了这个。 - a_local_nobody
2
升级从v1到v2后,我花了一年时间从一个模块到另一个模块寻找错误。+.+ - Seakleng Say

3
 single { MessagesRepositoryImpl() as MessagesRepository }

Yamashiro Rion you can do this


这对我们来说是有效的,但我们很难理解为什么使用不安全的类型转换解决了问题。 - John Franke
这对我们来说是有效的,但是我们很难理解为什么使用不安全的类型转换解决了问题。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接