Компонент теста кинжала не создается, когда проект содержит несколько модулей Android

Android Studio 3.4
kotlin 1.3.0
dagger 2.21

У меня есть проект с модулями presentation и data. И я пытаюсь создать тестовый компонент в модуле данных. Я могу сгенерировать компонент для модуля презентации. Я использую kotlin-kts для сборки gradle.

Для модуля презентации у меня есть следующие build.gradle.kts

plugins {
    id("com.android.application")
    kotlin("android")
    kotlin("kapt")
}

android {
    compileSdkVersion(Versions.compileSdkVersion)

    defaultConfig {
        applicationId = "nz.org.westforce.mobileui"
        minSdkVersion(Versions.minSdkVersion)
        targetSdkVersion(Versions.targetSdkVersion)
        versionCode = Versions.versionCode
        versionName = Versions.versionName

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
}

dependencies {
    implementation(Libraries.appCompat)
    implementation(Libraries.kotlinStdlib)
    implementation(Libraries.daggerAndroid)
    implementation(Libraries.daggerSupport)
    kapt(Libraries.daggerCompiler)
    kapt(Libraries.daggerProcessor)

    androidTestImplementation(TestLibraries.runner)
    androidTestImplementation(TestLibraries.espressoCore)

    testImplementation(TestLibraries.junit)
    testImplementation(Libraries.daggerAndroid)
    testImplementation(Libraries.daggerSupport)

    kaptTest(Libraries.daggerCompiler)
    kaptTest(Libraries.daggerProcessor)

    implementation(project(":data"))
}

Для модуля презентации у меня есть следующее приложение:

class WestforceCreditUnionMobileuiApplication
    : Application(), HasActivityInjector {

    @Inject
    lateinit var dispatchingAndroidActivityInjector: DispatchingAndroidInjector<Activity>

    override fun onCreate() {
        super.onCreate()

        DaggerWestforceCreditUnionMobileuiComponent.builder()
            .application(this)
            .build()
            .inject(this)
    }

    override fun activityInjector(): AndroidInjector<Activity> =
        dispatchingAndroidActivityInjector
}

Компонент

@Singleton
@Component(modules = [AndroidSupportInjectionModule::class])
interface WestforceCreditUnionMobileuiComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: WestforceCreditUnionMobileuiApplication): Builder

        fun build(): WestforceCreditUnionMobileuiComponent
    }

    fun inject(application: WestforceCreditUnionMobileuiApplication)
}

Вышеупомянутое работает, и генерируется DaggerWestforceCreditUnionMobileuiComponent

Теперь в моем модуле data я могу попытаться создать тестовый компонент, но кинжал не генерирует классы тестовых компонентов.

У меня есть следующий тестовый компонент в каталоге java/test/package/di

@Singleton
@Component(modules = [TestNetworkModule::class])
interface TestWestforceCeditUnionComponent {
    fun inject(webServicesImpTest: WebServicesImpTest)
}

И в моем тестовом классе:

class WebServicesImpTest {

    @Inject
    private lateinit var webServicesImp: WebServicesImp

    @Test
    fun setUp() {
        /* the DaggerTestWestforceCreditUnionComponent is not generated */
    }
}

Я не указал здесь модули, так как это слишком сильно раздует код.

Для моего build.gradle.kts в модуле данных:

import org.gradle.kotlin.dsl.implementation

plugins {
    id("com.android.library")
    id("kotlin-android")
}

android {
    compileSdkVersion(Versions.compileSdkVersion)

    defaultConfig {
        minSdkVersion(Versions.minSdkVersion)
        targetSdkVersion(Versions.targetSdkVersion)
        versionCode = Versions.versionCode
        versionName = Versions.versionName

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
}

dependencies {
    implementation(Libraries.kotlinStdlib)
    implementation(Libraries.appCompat)
    implementation(Libraries.daggerAndroid)
    implementation(Libraries.daggerSupport)
    kapt(Libraries.daggerCompiler)
    kapt(Libraries.daggerProcessor)

    testImplementation(TestLibraries.junit)
    testImplementation(TestLibraries.assertJ)
    testImplementation(TestLibraries.mockitoKotlin)

    testImplementation(Libraries.daggerAndroid)
    testImplementation(Libraries.daggerSupport)
    kaptTest(Libraries.daggerCompiler)
    kaptTest(Libraries.daggerProcessor)
}

Я использую следующие зависимости dagger.android:

  const val daggerAndroid = "com.google.dagger:dagger-android:${Versions.daggerAndroidVersion}"
  const val daggerCompiler = "com.google.dagger:dagger-compiler:${Versions.daggerAndroidVersion}"
  const val daggerProcessor = "com.google.dagger:dagger-android-processor:${Versions.daggerAndroidVersion}"
  const val daggerSupport = "com.google.dagger:dagger-android-support:${Versions.daggerAndroidVersion}"

Я попытался перестроить проект и запустить следующую задачу compileDebugUnitTestSources

Все строится удачно,

Одна мысль, о которой я думаю, поскольку я использую разные модули Android, может быть, модуль данных не может видеть WestforceCreditUnionMobileuiApplication в модуле презентации.

Большое спасибо за любые предложения


person ant2009    schedule 24.03.2019    source источник
comment
Можешь попробовать запустить assembleAndroidTest   -  person Skizo-ozᴉʞS    schedule 26.03.2019
comment
Я действительно пробовал это уже. Я думаю, проблема в том, что у меня есть 2 модуля Android presentation и data. Приложение находится в презентации, и, возможно, модуль data этого не видит.   -  person ant2009    schedule 27.03.2019
comment
Куда вы поместите это TestWestforceCeditUnionComponent?   -  person Archie G. Quiñones    schedule 27.03.2019
comment
Можете ли вы извлечь простую настройку на github и поделиться ссылкой?   -  person azizbekian    schedule 27.03.2019
comment
@azizbekian Репозиторий находится здесь: github.com/steve1rm/WestcreditUnion. Еще раз спасибо за вашу помощь. Проблема связана с модулем data. Я пытаюсь создать компонент кинжала в WebServicesImpTest.kt Однако кинжал не генерирует компонент. Я думаю, это потому, что приложение находится в модуле mobileui. Еще раз спасибо за ваш отзыв.   -  person ant2009    schedule 27.03.2019
comment
@azizbekian Я добавил вас как Collaborator в этот репозиторий.   -  person ant2009    schedule 27.03.2019
comment
@ ant2009, я скачал Android Studio 3.4 RC2, но не могу импортировать проект (ветвь master). Можете ли вы сказать, что мне не хватает в вашей настройке? В чем проблема с моим импортом?   -  person azizbekian    schedule 28.03.2019
comment
@azizbekian Я тоже использую AS 3.4 RC2. Я только что создал чистый каталог на своем локальном компьютере и клонировал это репо. Вместо того, чтобы импортировать проект, я сделал следующее open an existing android studio project И выбрал корень build.gradle.kts   -  person ant2009    schedule 28.03.2019
comment
@azizbekian проект открылся нормально, и я смог его построить. В проекте используются скрипты kotlin для сборки gradle.   -  person ant2009    schedule 28.03.2019
comment
@ant2009, извините, что не смог помочь. Пока Dmide опубликовал ответ, очевидно, что он смог построить проект, поэтому проблема в моей настройке. Надеюсь, решение Dmide работает для вас.   -  person azizbekian    schedule 28.03.2019
comment
@azizbekian спасибо за ваше время и помощь. Я проверю решение Dmide   -  person ant2009    schedule 29.03.2019


Ответы (1)


Вы забыли добавить

kotlin("kapt")

в раздел plugins модуля :data build.gradle.kts.

Затем Gradle выдает ошибки об отсутствии @Provides для вашего WebServicesImp. Также вы должны исправить отсутствующий поставщик Context, в моем примере я просто удалил использование Context. Это следует добавить к TestNetworkModule:

@Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
    return Retrofit.Builder()
        .baseUrl("http://www.holidaywebservice.com")
        .client(okHttpClient)
        .addConverterFactory(SimpleXmlConverterFactory.createNonStrict(Persister(AnnotationStrategy())))
        .build()
}
@Reusable
@Provides
fun provideWebServices(retrofit: Retrofit): WebServices {
    return retrofit.create(WebServices::class.java)
}

@Reusable
@Provides
fun provideWebServicesImp(webServices : WebServices): WebServicesImp {
    return WebServicesImp(webServices)
}

После этого DaggerTestWestforceCeditUnionComponent был успешно сгенерирован.

person Dmide    schedule 28.03.2019
comment
Спасибо, сработало, спасибо за помощь. plugins { id("com.android.library") id("kotlin-android") kotlin("android") kotlin("kapt") } Я добавил вышеуказанные плагины. У меня какая-то путаница с ними. Можете ли вы объяснить о них? - person ant2009; 29.03.2019
comment
kotlin(android) включает поддержку kotlin в этом модуле (id(kotlin-android) - это тот же самый метод, но другой), kotlin(kapt) включает обработку аннотаций в этом модуле, что требуется для работы кинжала. - person Dmide; 29.03.2019