Ошибка Hilt при предоставлении базового 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)
    }
}

Чтобы предоставить тестовую базовую ссылку для тестируемой конфигурации Mockwebserver, я реализовал функции внутри классов MyApplication и MyApplicationTest.

Мое приложение.класс

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


person dudi    schedule 01.08.2020    source источник


Ответы (1)


A) Возможное решение для вашего случая

Hilt не может предоставить ваш точный экземпляр MyApplication, он может предоставить только общий экземпляр Application (см. Component default bindings из Компоненты рукояти).

Это должно решить проблему:

@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"
    }

}
person Bartek Lipinski    schedule 07.08.2020
comment
После того, как я попробовал то же самое, мне не удалось заставить его работать. Я создал BaseUrlModule как для src/main/, так и для src/androidTest, и мои тесты пользовательского интерфейса получают только тот, который вводится в src/ main/ Есть идеи? - person Fernando Prieto Moyano; 16.11.2020