我正在尝试使用剑柄注入注入JUnit5/Jupiter测试用例,但遇到空指针异常。使用JUnit4一切正常。
重现一个简单的测试用例就足够了。
我的项目gradle文件
// 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
}
我的模块gradle文件
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()
}
我的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)
在我看来,HiltAndroidLaw
没有初始化,但我不知道为什么。
有人知道吗?
HiltAndroidLaw
未初始化,因为@Law
仅JUnit4支持,但您在此处使用的是JUnit5。如果Android支持像JUnit5这样的新框架,那就太好了,但这似乎不会很快发生。
所以你有几个选择,你可以:
@ExententBy
使JUnit5等效。这篇文章可能会有帮助?我想我会推荐#1,这样您就不必维护自己的JUnit5扩展,但它可能比我想象的更容易。