Ошибка рукояти, указав базовый 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()
}

При этом есть гораздо более элегантный способ реализовать это.

Б) Элегантный способ

  1. В src/main/your/package/ Создай UrlModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object UrlModule {

    @Provides
    fun providesBaseUrl(application: MyApplication): String {
        return "https://www.foo-production.com"
    }

}
  1. В 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"
    }

}
Другие вопросы по тегам