android - JUnit 本地测试 - Android 上下文“未注册仪器!”
问题描述
预期的
如 Android 文档构建本地单元测试示例MyLocalUnitTestClass中所述,在本地 JUnit测试中访问 Android上下文。
观察到的
运行时错误
java.lang.IllegalStateException:未注册检测!必须在注册仪器下运行。
执行
尝试的实现也可以在 Coinverse Open App GitHub 项目的test/poc分支下找到。
目录-应用程序 > src > 测试 > java
ExampleUnitTest.kt
package app.coinverse
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import org.junit.Assert.assertEquals
import org.junit.Test
class ExampleUnitTest {
val context = ApplicationProvider.getApplicationContext<Context>()
@Test
fun addition_isCorrect() {
FirebaseHelper.initialize(context)
assertEquals(4, 2 + 2)
}
}
build.gradle(模块:app)
库依赖项基于设置您的测试环境文档和Android 测试 Codelab build.gradle配置。唯一实现的测试类型是本地单元测试。但是,为了以防万一,包括Android 单元和仪器测试的依赖项。
以下是与测试相关的代码/库。
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 24
targetSdkVersion 28
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
}
// Gradle automatically adds 'android.test.runner' as a dependency.
useLibrary 'android.test.runner'
useLibrary 'android.test.base'
useLibrary 'android.test.mock'
testOptions {
unitTests.includeAndroidResources = true
}
}
dependencies {
// Testing
// Local Unit
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.19.0'
testImplementation "org.hamcrest:hamcrest-all:1.3"
testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.2.1"
testImplementation "org.robolectric:robolectric:4.3"
testImplementation 'androidx.test.espresso:espresso-core:3.2.0'
testImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
testImplementation 'androidx.test.espresso:espresso-intents:3.2.0'
testImplementation 'com.google.truth:truth:0.44'
// Android Unit
androidTestImplementation 'junit:junit:4.12'
androidTestImplementation 'org.mockito:mockito-core:2.19.0'
androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito:2.12.1"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.2.1"
// AndroidX - JVM
testImplementation "androidx.test:core-ktx:1.2.0"
testImplementation "androidx.test.ext:junit-ktx:1.1.1"
testImplementation "androidx.test:rules:1.2.0"
implementation "androidx.fragment:fragment-testing:1.2.0-alpha02"
implementation "androidx.test:core:1.2.0"
implementation "androidx.fragment:fragment:1.2.0-alpha02"
// Instrumented testing
androidTestImplementation "androidx.test:core-ktx:1.2.0"
androidTestImplementation "androidx.test.ext:junit-ktx:1.1.1"
androidTestImplementation "androidx.test:rules:1.2.0"
androidTestImplementation "androidx.room:room-testing:2.1.0"
androidTestImplementation "androidx.arch.core:core-testing:2.0.1"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
androidTestImplementation "androidx.test.espresso:espresso-contrib:3.2.0"
androidTestImplementation "androidx.test.espresso:espresso-intents:3.2.0"
androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:3.2.0"
androidTestImplementation "org.robolectric:annotations:4.3"
implementation "androidx.test.espresso:espresso-idling-resource:3.2.0"
// Resolve conflicts between main and test APK:
androidTestImplementation "androidx.annotation:annotation:1.1.0"
androidTestImplementation "androidx.legacy:legacy-support-v4:1.0.0"
androidTestImplementation "androidx.recyclerview:recyclerview:1.0.0"
androidTestImplementation "androidx.appcompat:appcompat:1.0.2"
androidTestImplementation "com.google.android.material:material:1.0.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
尝试的解决方案
- 文件 > 使缓存无效并重新启动...
- 在运行测试之前启动 Context 会导致相同的运行时错误。
ExampleUnitTest.kt
@Before
fun setup() {
val context = getApplicationContext<Context>()
}
- 将ExampleUnitTest.kt类移动到sharedTest目录中,如测试代码实验室的运行您的第一个测试部分中所述。
目录- app > src > sharedTest > java
build.gradle(模块:app)
android {
sourceSets {
String sharedTestDir = 'src/sharedTest/java'
test {
java.srcDir sharedTestDir
}
androidTest {
java.srcDir sharedTestDir
}
}
}
附录
完整的错误信息
java.lang.IllegalStateException:未注册检测!必须在注册仪器下运行。
在 androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
在 androidx.test.core.app.ApplicationProvider.getApplicationContext(ApplicationProvider.java:41)
在 app.coinverse.ExampleUnitTest.setup(ExampleUnitTest.kt:29) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在 java.lang.reflect.Method.invoke(Method.java:498)
在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
在 org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
在 org.junit.runners.ParentRunner.run(ParentRunner.java:363)
在 org.junit.runner.JUnitCore.run(JUnitCore.java:137)
在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
在 com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
解决方案
解决方案
AndroidViewModel
将实现重构ViewModel
为Jose Alcérreca的帖子Locale changes 和 AndroidViewModel 反模式中所述
此重构将消除创建应用程序上下文的需要。
除了 ViewModel 重构之外,将组件作为参数传递给 ViewModel 以分离依赖项。可以在新的 ViewModel 中使用依赖注入库来创建所需的组件(即,存储库、数据库、分析等)并将它们与 ViewModel 解耦。
推荐阅读
- iframe-resizer - 使用 iframe-resizer 获取未捕获的 TypeError
- swift - 带有模型观察器的 Swift MVC 架构
- ios - 从 URL 异步加载图像到单元格中的 UIImageView 不会在初始加载时加载
- r - 迭代 R 中的增量栅格值以创建新的栅格数据集
- python - 在 Python Turtle 中将圆半径与窗口大小联系起来
- ios - Swift iOS -how to cancel DispatchGroup() from managing a loop
- c# - 枚举器的初始化
- php - 传递字符串参数时有没有办法让IDE PHP代码自动完成?
- swift - 在某些情况下,使用 searchController 推动转换不会平滑地更改导航栏的大小
- python - 如何在 tkinter 上使用单选按钮