Ошибка рукояти, указав базовый URL-адрес для Mockwebserver
В своем приложении я использую Hilt для внедрения зависимостей. Я реализовалRetrofitModule
чтобы предоставить ему зависимости в моем репозитории следующим образом:
@Module
@InstallIn(ApplicationComponent::class)
object RetrofitModule {
@Singleton
@Provides
fun providesRetrofitClient(okHttpClient: OkHttpClient, baseUrl: String): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
@Provides
fun providesBaseUrl(application: MyApplication): String {
return application.getBaseUrl()
}
@Singleton
@Provides
fun providesOkHttpClient(): OkHttpClient {
val okHttpClientBuilder = OkHttpClient.Builder()
val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
okHttpClientBuilder.addInterceptor(loggingInterceptor)
return okHttpClientBuilder.build()
}
@Singleton
@Provides
fun providesService(retrofit: Retrofit): MyService {
return retrofit.create(MyService::class.java)
}
}
Чтобы предоставить тестовый базовый URL для тестируемой конфигурации Mockwebserver, я реализовал функции внутри MyApplication
а также MyApplicationTest
класс
MyApplication.class
class MyApplication : Application() {
fun getBaseUrl() = "https://www.foo-production.com"
}
MyApplicationTest.class
class MyApplicationTest : Application() {
fun getBaseUrl() = "http://127.0.0.1:8080"
}
Но когда я создаю приложение, я получаю эту ошибку:
A binding with matching key exists in component: de.xxx.xxx.MyApplication_HiltComponents.ApplicationC
...
Думаю проблема в этом методе
@Provides
fun providesBaseUrl(application: MyApplication): String {
return application.getBaseUrl()
}
и есть проблема с предоставлением класса MyApplication
1 ответ
A) Возможное решение для вашего случая
Hilt не может предоставить ваши точные данные MyApplication
например, он может предоставить только общий Application
экземпляр (см. Component default bindings
от Hilt Components).
Это должно решить проблему:
@Provides
fun providesBaseUrl(application: Application): String {
return (application as MyApplication).getBaseUrl()
}
При этом есть гораздо более элегантный способ реализовать это.
Б) Элегантный способ
- В
src/main/your/package/
СоздайUrlModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object UrlModule {
@Provides
fun providesBaseUrl(application: MyApplication): String {
return "https://www.foo-production.com"
}
}
- В
src/test/your/package/
(илиsrc/androidTest/your/package/
если это для тестов пользовательского интерфейса) создайте другойUrlModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object UrlModule {
@Provides
fun providesBaseUrl(application: MyApplication): String {
return "http://127.0.0.1:8080"
}
}