I'm trying to test ViewModel(AndroidViewModel parent), in unit tests(test folder) but when using
val application = ApplicationProvider.getApplicationContext<Application>()
it gives me this error
java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
ExampleUnitTest
class ExampleUnitTest {
private lateinit var myAndroidViewModel: MyAndroidViewModel
private val app = ApplicationProvider.getApplicationContext<Application>()
@Before
fun init() {
myAndroidViewModel = MyAndroidViewModel(app)
}
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
build.gradle
android {
testOptions {
unitTests.returnDefaultValues = true
}
}
dependencies {
testImplementation 'junit:junit:4.12'
testImplementation 'androidx.test:core-ktx:1.3.0'
}
If I use robolectric, I no longer get said error, but I don't feel that it is a good option, since robolectric is more for ui test.
I hope you can help me. Thanks.
You can use Robolectric in a Unit Test, inside test directory, and choose the platform Application class.
@RunWith(RobolectricTestRunner::class)
@Config(application = Application::class)
class ViewModelTest {
@Test
@Throws(Exception::class)
fun someTest() {
val application = RuntimeEnvironment.application
val testViewModel = MyAndroidViewModel(application)
testViewModel.foo()
}
}
Or you can use an InstrumentationTest inside androidTest directory, and cast the InstrumentationRegistry.getTargetContext().applicationContext to Application:
@RunWith(AndroidJUnit4::class)
class ViewModelTest {
@Test
@Throws(Exception::class)
fun someTest() {
val application = ApplicationProvider.getApplicationContext() as Application
val testViewModel = MyAndroidViewModel(application)
testViewModel.foo()
}
}
Hope it helped!
For Unit testing, one may want to use @ActivityScoped
and then @Inject
the constructor
...
But for testing ViewModel
I'd rather use androidx.hilt:hilt-lifecycle-viewmodel
:
dependencies {
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
// When using Kotlin.
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
// When using Java.
annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
}
Then one can @ViewModelInject
:
class ExampleViewModel @ViewModelInject constructor(
private val repository: ExampleRepository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
...
}
See Hilt and Jetpack integrations.
Here's another one example using Hilt with MockK, which it's author summarizes as:
Testing with Hilt, just
@UninstallModules
and then@BindValue
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With