NullPointerException при попытке инъекции рукояти в тестовых примерах JUnit5/Jupiter

Я пытаюсь ввести тестовый пример JUnit5/Jupiter с инъекцией рукояти, но получаю исключение нулевого указателя. С JUnit4 все работает.

Для воспроизведения достаточно простого тестового примера.

файл градиента моего проекта

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = '1.5.20-M1'
    ext.hilt_version = '2.35'

    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath("de.mannodermaus.gradle.plugins:android-junit5:1.7.1.1")
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

мой файл градиента модуля

plugins {
    id 'com.android.application'
    id("dagger.hilt.android.plugin")
    id("de.mannodermaus.android-junit5")
}
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "de.negosa.myhilttestingapplication"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "de.negosa.myhilttestingapplication.HiltTestRunner"
        // 2) Connect JUnit 5 to the runner
        testInstrumentationRunnerArgument("runnerBuilder", "de.mannodermaus.junit5.AndroidJUnit5Builder")
    }

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

dependencies {

    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'com.google.android.material:material:1.3.0'

    // Kotlin
    implementation "androidx.core:core-ktx:1.5.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    // Hilt
    implementation("com.google.dagger:hilt-android:$hilt_version")
    kapt("com.google.dagger:hilt-android-compiler:$hilt_version")

    //
    // Local Testing

    // (Required) Writing and executing Unit Tests on the JUnit Platform
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1")

    // (Optional) If you also have JUnit 4-based tests
    testImplementation 'junit:junit:4.13.2'
    testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.7.1")

    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    //
    // Instrumented Testing
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    // hilt testing
    androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
    // ...with Kotlin.
    kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
    // 4) Jupiter API & Test Runner, if you don't have it already
    androidTestImplementation("androidx.test:runner:1.3.0")
    androidTestImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1")

    // 5) The instrumentation test companion libraries
    androidTestImplementation("de.mannodermaus.junit5:android-test-core:1.2.2")
    androidTestRuntimeOnly("de.mannodermaus.junit5:android-test-runner:1.2.2")

}
repositories {
    mavenCentral()
}

my HiltTestRunner

package de.negosa.myhilttestingapplication

import android.app.Application
import android.content.Context
import androidx.test.runner.AndroidJUnitRunner
import dagger.hilt.android.testing.HiltTestApplication

class HiltTestRunner : AndroidJUnitRunner() {

    override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
        return super.newApplication(cl, HiltTestApplication::class.java.name, context)
    }
}

и мой тестовый файл

package de.negosa.myhilttestingapplication

import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Rule

import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test


@HiltAndroidTest
class HiltTestingTest {
    @get: Rule
    var hiltRule = HiltAndroidRule(this)
    
    @BeforeEach
    fun setup() {
        hiltRule.inject()
    }

    @Test
    fun simpleTest() {

    }
}

Сообщение об ошибке

java.lang.NullPointerException
    at dagger.hilt.internal.Preconditions.checkNotNull(Preconditions.java:34)
    at dagger.hilt.android.internal.testing.TestApplicationComponentManager.inject(TestApplicationComponentManager.java:250)
    at dagger.hilt.android.internal.testing.MarkThatRulesRanRule.inject(MarkThatRulesRanRule.java:81)
    at dagger.hilt.android.testing.HiltAndroidRule.inject(HiltAndroidRule.java:49)
    at de.negosa.myhilttestingapplication.HiltTestingTest.setup(HiltTestingTest.kt:18)
    at java.lang.reflect.Method.invoke(Native Method)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeEachMethod(TimeoutExtension.java:76)
    at org.junit.jupiter.engine.descriptor.-$$Lambda$bFHzkK-Gyd2nGL9G6f3WT3eZ7lM.apply(Unknown Source:0)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.-$$Lambda$ExecutableInvoker$ReflectiveInterceptorCall$AfiRfaQW5MFAa8lovVwndaKa8l0.apply(Unknown Source:2)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.-$$Lambda$ExecutableInvoker$hmdF2IKSQSF2OJBv_amWUUg0sS8.apply(Unknown Source:6)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeMethodInExtensionContext(ClassBasedTestDescriptor.java:490)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$synthesizeBeforeEachMethodAdapter$19$ClassBasedTestDescriptor(ClassBasedTestDescriptor.java:475)
    at org.junit.jupiter.engine.descriptor.-$$Lambda$ClassBasedTestDescriptor$tNV5uTg6yzrSAyoR9_LyHRWjPVk.invokeBeforeEachMethod(Unknown Source:4)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachMethods$2$TestMethodTestDescriptor(TestMethodTestDescriptor.java:167)
    at org.junit.jupiter.engine.descriptor.-$$Lambda$TestMethodTestDescriptor$pK5fUoWT43xVHP3Wk-jdF7k0URU.invoke(Unknown Source:6)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$5(TestMethodTestDescriptor.java:195)
    at org.junit.jupiter.engine.descriptor.-$$Lambda$TestMethodTestDescriptor$Y4hAX5bQnGBfYTu_BFBCUC1ErL0.execute(Unknown Source:6)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:195)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachMethods(TestMethodTestDescriptor.java:164)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5$NodeTestTask(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$oEtjVUBr1dzvAyO4rHrqPrrp8iU.execute(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7$NodeTestTask(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$sIF-wJyqQcSlbWMGWi7dBYWbuCo.invoke(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8$NodeTestTask(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$EAUqZA5CfD8zbN3AlxhbCoS66eU.execute(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$04TgCUAyYTiSsbqaEl88v4bsMqI.accept(Unknown Source:2)
    at java.util.ArrayList.forEach(ArrayList.java:1262)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5$NodeTestTask(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$oEtjVUBr1dzvAyO4rHrqPrrp8iU.execute(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7$NodeTestTask(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$sIF-wJyqQcSlbWMGWi7dBYWbuCo.invoke(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8$NodeTestTask(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$EAUqZA5CfD8zbN3AlxhbCoS66eU.execute(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$04TgCUAyYTiSsbqaEl88v4bsMqI.accept(Unknown Source:2)
    at java.util.ArrayList.forEach(ArrayList.java:1262)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5$NodeTestTask(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$oEtjVUBr1dzvAyO4rHrqPrrp8iU.execute(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7$NodeTestTask(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$sIF-wJyqQcSlbWMGWi7dBYWbuCo.invoke(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8$NodeTestTask(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.-$$Lambda$NodeTestTask$EAUqZA5CfD8zbN3AlxhbCoS66eU.execute(Unknown Source:2)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0$EngineExecutionOrchestrator(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.-$$Lambda$EngineExecutionOrchestrator$eWp5Nw-Kiu1gM4ryu2PhdSQR8rg.accept(Unknown Source:8)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84)
    at de.mannodermaus.junit5.AndroidJUnit5.run(AndroidJUnit5.java:126)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
    at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2205)

Мне кажется, что HiltAndroidRule не инициализирован, но я не знаю, почему.

У кого-нибудь есть идеи?


person Manuel Siebeneicher    schedule 07.06.2021    source источник


Ответы (1)


HiltAndroidRule не инициализирован, потому что @Rule поддерживаются только JUnit4, а здесь вы используете JUnit5. Было бы неплохо, если бы Android поддерживал новый фреймворк, такой как JUnit5, но похоже, что этого не произойдет. в ближайшее время.

Итак, у вас есть несколько вариантов, вы можете:

  1. Используйте JUnit4, как вы уже успешно это сделали.
  2. Или вы можете сделать эквивалент JUnit5 с @ExtendWith. Этот пост может быть полезен?

Думаю, я бы просто порекомендовал №1, чтобы вам не приходилось поддерживать собственное расширение JUnit5, но это может быть проще, чем я думаю.

person Nick Ellis    schedule 18.07.2021