Android Внедрение тестовых зависимостей с помощью Dagger: отсутствует или конфликтует зависимость - PullRequest
0 голосов
/ 27 марта 2020

Я хочу внедрить зависимости в android тестах с использованием кинжала.

Я создал простое приложение с AppComponent, расширяющим AndroidInjector. Это работает для самого приложения (код встроен / собран кинжалом).

Затем для / test я также создал AppComponentTest и AppTest.

Это заняло у меня некоторое время понял, что мне нужно создать простой тест и запустить его, чтобы позволить gradle создать / build для теста. Теперь код есть, но есть некоторая ошибка в этом сгенерированном коде, как вы можете видеть здесь:

AppTest.kt

DaggerAppComponentTest auto generated

AppComponent.kt

@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class
    ]
)
interface AppComponent : AndroidInjector<App> {
    @Component.Factory
    interface Factory {
        fun create(@BindsInstance application: Application): AppComponent
    }
}

App.kt

open class App : Application(), HasAndroidInjector {
    @Inject
    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>

    override fun androidInjector(): AndroidInjector<Any> = dispatchingAndroidInjector

    override fun onCreate() {
        super.onCreate()
        setupDagger()
    }

    @VisibleForTesting
    open fun setupDagger() {
        DaggerAppComponent
            .factory()
            .create(this)
            .inject(this)
    }
}

Тогда под той же структурой, но в / test Я создал это:

AppComponentTest.kt

@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class
    ]
)
interface AppComponentTest : AppComponent {
    @Component.Factory
    interface Factory {
        fun create(
            @BindsInstance application: Application
        ): AppComponentTest
    }
}

AppTest.kt

class AppTest : App() {
    override fun setupDagger() {
        DaggerTestAppComponent
            .factory()
            .create(this)
            .inject(this)
    }
}

А это build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"

    defaultConfig {
        applicationId "com.example.dagger"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    testOptions {
        unitTests {
            includeAndroidResources = true
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'

    def dagger_version = "2.27"
    implementation "com.google.dagger:dagger-android:$dagger_version"
    implementation "com.google.dagger:dagger-android-support:$dagger_version"
    kapt "com.google.dagger:dagger-android-processor:$dagger_version"
    kapt "com.google.dagger:dagger-compiler:$dagger_version"

    testImplementation 'junit:junit:4.13'
    kaptTest "com.google.dagger:dagger-compiler:$dagger_version"

    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

Также наивный тест: ExampleUnitTest.kt

@RunWith(JUnit4::class)
class ExampleUnitTest {
    @Test
    fun test() {
        assert(true)
    }
}

Я также пытался с другим подходом, используя это: AppComponentTest2.kt

@Singleton
@Component(modules = [])
interface AppComponentTest2 {
    fun inject(test: ExampleUnitTest2)
}

ExampleUnitTest2.kt

@RunWith(JUnit4::class)
class ExampleUnitTest2 {
    @Test
    fun test() {
        DaggerAppComponentTest2
            .builder()
            .build()
            .inject(this)
        assert(true)
    }
}

А также та же ошибка:

ExampleUnitTest2.kt

DaggerAppComponentTest2.kt


Кстати, это это репо с этим кодом: https://gitlab.com/fitu/dagger

Там есть две ветви first_approach и second_approach


РЕДАКТИРОВАТЬ 1: У меня был другой репозиторий, где я мог сделать эту инъекцию, и теперь я попробовал, и это не работает.

Сравнение зависимостей, которые у меня есть:

Новый проект:

classpath 'com.android.tools.build:gradle:3.6.1'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61'

implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.61'

implementation 'com.google.dagger:dagger-android:2.27'
implementation 'com.google.dagger:dagger-android-support:2.27'
kapt 'com.google.dagger:dagger-android-processor:2.27'
kapt 'com.google.dagger:dagger-compiler:2.27'

kaptTest 'com.google.dagger:dagger-compiler:2.27'

Старый проект:

classpath 'com.android.tools.build:gradle:3.2.0'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.70'

implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.61'
implementation'com.google.dagger:dagger-android-support:2.14.1'
kapt 'com.google.dagger:dagger-compiler:2.14.1'

kaptTest 'com.google.dagger:dagger-compiler:2.14.1'

Так что, похоже, это не кинжал или kotlin версия.

Возможно, это связано с Android Studio?

Я не уверен насчет версии AS, когда я создал этот старый проект, но моя текущая версия AS: 3.6.1


РЕДАКТИРОВАТЬ 2: Я удалил почти все в проекте, главную папку с приложением и все: All deleted

Единственное напоминание было два класса: AppComponentTest.kt и ExampleUnitTest.kt

@Singleton
@Component(modules = [])
interface AppComponentTest
class ExampleUnitTest {
    @Test
    fun test() {
        DaggerAppComponentTest
            .builder()
            .build()

        assert(true)
    }
}

Ошибка сохраняется, поэтому я предполагаю, что проблема может заключаться в комбинациях версии AS, Kotlin версия и / или версия Dagger.

...