Ошибка рукоятки, указав базовый URL-адрес для Mockwebserver - PullRequest
1 голос
/ 01 августа 2020

В моем приложении я использую 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 class

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 Ответ

1 голос
/ 07 августа 2020

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

Hilt не может предоставить ваш точный MyApplication экземпляр, он может предоставить только общий c 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"
    }

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

}
...