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

时间:2019-08-17 11:19:25

标签: android unit-testing kotlin dependency-injection koin

koin测试结果如下:

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

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() }
}

在应用程序类中:

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'

4 个答案:

答案 0 :(得分:6)

我遇到了同样的问题,但就我而言,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()) }

答案 1 :(得分:1)

我发现了问题,错误是模块而不是模块(或.koin.core.KoinApplication)

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

因此,解决方案和正确的版本是:

    startKoin { modules(loginUtilsModule) }

答案 2 :(得分:0)

 single { MessagesRepositoryImpl() as MessagesRepository }

山代里翁,您可以这样做

答案 3 :(得分:0)

我在重构我的网络模块时遇到了类似的错误。请在下面找到网络模块。

private const val TIME_OUT = 30L

val NetworkModule = module {

single { createService(get()) }

single { createRetrofit(get(), BuildConfig.BASE_URL) }

single { createOkHttpClient() }

single { MoshiConverterFactory.create() }

single { Moshi.Builder().build() }

}

fun createOkHttpClient(): OkHttpClient {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BASIC
return OkHttpClient.Builder()
    .connectTimeout(TIME_OUT, TimeUnit.SECONDS)
    .readTimeout(TIME_OUT, TimeUnit.SECONDS)
    .addInterceptor(httpLoggingInterceptor).build()
}

fun createRetrofit(okHttpClient: OkHttpClient, url: String): Retrofit {
return Retrofit.Builder()
    .baseUrl(url)
    .client(okHttpClient)
    .addConverterFactory(MoshiConverterFactory.create()).build()
}

fun createService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}

fun createUsersRepository(apiService: ApiService): UserRepository {
return UserRepositoryImpl(apiService)
}

将 createUsersRepository 移动到单独的存储库模块时出现问题。请提供一些解决方案或让我知道我做错了什么。

请在下面找到存储库模块。

val RepositoryModule = module {

single { UserRepositoryImpl(get()) }
}