【问题标题】:Koin: NoBeanDefFoundException, Check your module definitionsKoin:NoBeanDefFoundException,检查你的模块定义
【发布时间】:2019-08-17 11:19:25
【问题描述】:

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'

【问题讨论】:

  • 你有没有试过去掉KoinComponent,只保留KoinTest做测试?
  • 是的,试过了。 KoinComponent 不是故意的。
  • 你能在此处的测试文件中添加你的导入并在 gradle 中测试依赖项吗?
  • @Napster 在问题中更新。

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


【解决方案1】:

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

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

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

    startKoin { modules(loginUtilsModule) }

【讨论】:

  • 拯救了我的一天,在 ViewModel 上遇到了同样的问题,感谢您找到这个
  • 从v1升级到v2后,我花了一年的时间从​​module到modules+.+发现一个错误
【解决方案2】:

我遇到了同样的问题,但在我的情况下,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()) }

【讨论】:

  • 这是我的问题,除了我在其他模块中解决了依赖关系。奇怪
【解决方案3】:
 single { MessagesRepositoryImpl() as MessagesRepository }

山城里翁你可以这样做

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多