Access the Android Context within a local JUnit test as outlined in the Android Documentation Build local unit tests example MyLocalUnitTestClass.
java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
The attempted implementation may also be found at the Coinverse Open App GitHub project under the test/poc branch.
Directory - app > src > test > 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 (Module: app)
The library dependencies are based both off of the Set up your testing environment documentation and the Android Testing Codelab build.gradle configuration. The only test type implemented is the Local Unit test. However, included are dependencies for Android Unit and Instrumented tests just in case.
Below is the code / libraries related to testing.
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"
}
ExampleUnitTest.kt
@Before
fun setup() {
val context = getApplicationContext<Context>()
}
Directory - app > src > sharedTest > java
build.gradle (Module: app)
android {
sourceSets {
String sharedTestDir = 'src/sharedTest/java'
test {
java.srcDir sharedTestDir
}
androidTest {
java.srcDir sharedTestDir
}
}
}
java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
at androidx.test.core.app.ApplicationProvider.getApplicationContext(ApplicationProvider.java:41)
at app.coinverse.ExampleUnitTest.setup(ExampleUnitTest.kt:29) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Refactor AndroidViewModel
implementation to ViewModel
as outlined in Jose Alcérreca's post Locale changes and the AndroidViewModel antipattern
This refactor will remove the need to create Application Context.
In addition to the ViewModel refactor, pass components into the ViewModel as an argument to separate dependencies. A Dependency Injection library may be used in the new ViewModel in order to create required components (ie — Repository, Database, Analytics, and etc.) and de-couple them from the ViewModel as well.