Unresolved androidx classes for writing unit tests - android

I am trying to write my first test and I have problem figuring out the right dependencies to get everything to work. Here is my test class
class EmployeeDatabaseTest {
private lateinit var employeeDao: EmployeeDAO
#Before
fun setup() {
EmployeeDatabase.TEST_MODE = true
employeeDao = EmployeeDatabase.getDatabase(??).employeeDao()
}
#Test
fun should_Insert_Employee_Item() {
val employee = Employee("xx", "xx", 31, Gender.MALE)
employee.id = 1
runBlocking { employeeDao.addNewEmployee(employee) }
val employeeTest = runBlocking { getValue(employeeDao.getEmployeeById(employee.id!!)) }
Assert.assertEquals(employee.name, employeeTest.name)
}
}
Normally I would obtain context by InstrumentationRegistry.getContext()...but InstrumentationRegistry can't be resolved. It also can't resolve getValue(..) method. I am new to testing but I bet is something with dependencies. Here is my build.gradle:
dependencies {
...
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
androidTestImplementation 'androidx.test:core:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
}
defaultConfig {
...
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Do I miss something I am I doing something wrong?

A simple Context can be resolved with
androidx.test.core.app.ApplicationProvider.getApplicationContext()
which is part of the core module
androidTestImplementation 'androidx.test:core:1.2.0'
When you use Robolectric, you can also have it as
testImplementation 'androidx.test:core:1.2.0'

Related

Unable to resolve dependency androidx.test:core:1.9.0-alpha01

I have tried lot but I having this issue try generate release build
Could not find androidx.test:core:1.9.0-alpha01.
Searched in the following locations:
- https://dl.google.com/dl/android/maven2/androidx/test/core/1.9.0-alpha01/core-1.9.0-alpha01.pom
- https://jcenter.bintray.com/androidx/test/core/1.9.0-alpha01/core-1.9.0-alpha01.pom
- https://repo.maven.apache.org/maven2/androidx/test/core/1.9.0-alpha01/core-1.9.0-alpha01.pom
Kindly assist me to resolve this error
Gradle :
ext {
// region Testing
junit_version = '4.13.2'
espresso_version = '3.5.0-alpha04'
mockito_version = '4.3.1'
mockito_android_version = '4.3.1'
test_version = '1.9.0-alpha01'
test_ext_version = '1.1.4-alpha04'
arch_testing_version = '2.1.0'
// endregion
}
android {
compileSdkVersion 32
}
androidExtensions {
experimental = true
}
dependencies {
// region Testing - JUnit
testImplementation "junit:junit:$junit_version"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutine_version"
testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp_version"
testImplementation "org.mockito:mockito-core:$mockito_version"
// endregion
// region Testing - Instrumented
androidTestImplementation "androidx.test:core:$test_version"
androidTestImplementation "androidx.test:runner:$test_version"
androidTestImplementation "androidx.test:monitor:$test_version"
androidTestImplementation "androidx.test:rules:$test_version"
androidTestImplementation "androidx.test.ext:junit:$test_ext_version"
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
androidTestImplementation "androidx.arch.core:core-testing:$arch_testing_version"
androidTestImplementation "androidx.room:room-testing:$room_version"
androidTestImplementation "org.mockito:mockito-core:$mockito_version"
androidTestImplementation "org.mockito:mockito-android:$mockito_android_version"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutine_version"
androidTestImplementation "com.squareup.okhttp3:mockwebserver:$okhttp_version"
androidTestUtil "androidx.test:orchestrator:$test_version"
// endregion
}
Try changing this:
test_version = '1.9.0-alpha01'
To this:
test_version = '1.4.1-alpha04'
(I think the version you declared doesn't exist: https://developer.android.com/jetpack/androidx/releases/test)
subprojects {
project.configurations.all {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'com.android.support'
&& !details.requested.name.contains('multidex') ) {
details.useVersion "version which should be used - in your case 26.0.0-beta2"
}
}
}
}

Hilt Test Unit with View Model, No Instrumentation Registered

I want to implementation Dependecy Injection using Hilt to ViewModel. And that working. but i can't test it. it show error. I was read some other post, but no one is answered.
This error maybe too many test dependency and conflict.
Version
Hilt version = 2.35.1
Android Studio = 4.2.1
Test class
simplest code won't run
package com.unlink.moviecatalogue6.ui.movie
import com.unlink.moviecatalogue6.data.repository.MovieRepository
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject
#HiltAndroidTest
class MovieViewModelTest {
#get:Rule var hiltrule = HiltAndroidRule(this)
#Inject
lateinit var repository: MovieRepository
#Before
fun setUp() {
hiltrule.inject()
}
#Test
fun some(){
//
}
}
Error
but error at #get:Rule
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 dagger.hilt.android.internal.testing.MarkThatRulesRanRule.<init>(MarkThatRulesRanRule.java:41)
at dagger.hilt.android.testing.HiltAndroidRule.<init>(HiltAndroidRule.java:36)
at com.unlink.moviecatalogue6.ui.movie.MovieViewModelTest2.<init>(MovieViewModelTest2.kt:19)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:250)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:260)
at org.junit.runners.BlockJUnit4ClassRunner$2.runReflectiveCall(BlockJUnit4ClassRunner.java:309)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
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 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Setup Custom Test Runner
i try make custom test runner
package com.unlink.moviecatalogue6
class CustomTestRunnerByMe : AndroidJUnitRunner() {
override fun newApplication(
cl: ClassLoader?,
className: String?,
context: Context?
): Application {
return super.newApplication(cl, HiltTestApplication::class.java.name, context)
}
}
here my full build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
buildFeatures{
viewBinding true
}
defaultConfig {
applicationId "com.unlink.moviecatalogue6"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
//custom test runner
testInstrumentationRunner "com.unlink.moviecatalogue6.CustomTestRunnerByMe"
//testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
// viewmodels
implementation 'androidx.activity:activity-ktx:1.2.3'
implementation 'androidx.fragment:fragment-ktx:1.3.3'
//image library
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.palette:palette-ktx:1.0.0'
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.2"
implementation "com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2"
//Kotlin Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_android_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_android_version"
//Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
kapt "androidx.hilt:hilt-compiler:1.0.0"
// default testing
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
// mockito testing
testImplementation "androidx.arch.core:core-testing:2.1.0"
testImplementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
//coroutine test
//For runBlockingTest, CoroutineDispatcher etc.
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2"
// hilt testing
// For Robolectric tests.
testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"
// For instrumented tests.
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
// Espresso dependencies
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-accessibility:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-web:$espresso_version"
androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$espresso_version"
}
kapt{
correctErrorTypes true
}
i was follow documentation at Hilt Documentation and Google Developer Document
Any response will very appreciate, Thanks for helping
Using RobolectricTestRunner ,we can run the test that depends on the android framework without emulator or real device.
ViewModel is a android library.So to test the ViewModel need to add RobolectricTestRunner.
For that first add dependency
//Unit test
testImplementation 'org.robolectric:robolectric:4.4'
//UI test
androidTestImplementation 'org.robolectric:robolectric:4.4'
Then Add these code above your test class.
#HiltAndroidTest
#RunWith(RobolectricTestRunner.class)
#Config(sdk = {Build.VERSION_CODES.VERSION_CODE}, application = HiltTestApplication.class)
public class HiltMainViewModelTest{
//your test code
}
Now your HiltCustomTestRunner will use RobolectricTestRunner to test android code.
package com.unlink.moviecatalogue6.ui.movie
import com.unlink.moviecatalogue6.data.repository.MovieRepository
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Before
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject
#HiltAndroidTest
#RunWith(AndroidJUnit4::class)
class MovieViewModelTest {
#get:Rule var hiltrule = HiltAndroidRule(this)
#Inject
lateinit var repository: MovieRepository
#Before
fun setUp() {
hiltrule.inject()
}
#Test
fun some(){
//
}
}
Add #RunWith(AndroidJUnit4::class)

Null pointer exception when stubbing

Good afternoon, I have a nullpointer exception when stubbing
package com.micheladrien.android.fresquerappel
import android.app.Application
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.micheladrien.fresquerappel.R
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.junit.MockitoJUnitRunner
#RunWith(MockitoJUnitRunner::class)
class MainViewModelTest {
#Rule
#JvmField
var instantTaskExecutorRule = InstantTaskExecutorRule()
#Mock
val applicationMock: Application = mock(Application::class.java)
#Before
fun setUpTaskDetailViewModel() {
`when`(applicationMock.getString(R.string.collage_climat)).thenReturn("Climat")
}
}
edit : I need to stub the function when(applicationMock.getString(R.string.collage_climat)).thenReturn("Climat")
because my viewmodel will get strings from context.
According to this blog post : https://codepills.com/2018/05/10/3-basic-mistakes-for-nullpointerexception-when-mock/
I should replace when thenreturn by when then (answer) which if it's true, why ?
I have already Tested : Changing R.id value to a brut number. => Same error
Mocking the file inside the before and using lateinit for the declaration at #Mock => same error
Unlike previous question thread Mockito - NullpointerException when stubbing Method
I am directly stubbing the method. Not stubbing the method of the object of another method.
Any help would be greatly appreciated.
Edit : The VM I aim to test :
class MainViewModel(application: Application): AndroidViewModel(application), WaitingViewModel{
private val _name = MutableLiveData<String>().apply {
value = application.getString(R.string.collage_climat)
}
val name : LiveData<String> = _name
override fun notifyNewCollage(collage_name: String) {
_name.value = collage_name
}
}
Here is the gradle if you want to check the Mockito version :
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.3'
def navigation_version = '2.3.1'
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.navigation:navigation-fragment:$navigation_version"
implementation "androidx.navigation:navigation-ui:$navigation_version"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
implementation 'il.co.theblitz:observablecollections:1.4.2'
def espressocore_version = '3.3.0'
androidTestImplementation "androidx.test.espresso:espresso-core:$espressocore_version"
androidTestImplementation "androidx.test.espresso:espresso-core:$espressocore_version"
androidTestImplementation "android.arch.core:core-testing:$lifecycle_version"
def mockito_version = '3.5.5' // For local unit tests on your development machine (also tested on 3.3.3)
testImplementation "org.mockito:mockito-core:$mockito_version" // For instrumentation tests on Android devices and emulators
androidTestImplementation "org.mockito:mockito-android:$mockito_version"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
}
Mockito advices against Mocking classes you don't own. So an Application mock is a bad idea.
Junit can give you the application context needed : https://developer.android.com/training/testing/junit-runner
For other info about stubbing fail, Mockito fails on stubbing : it tries to execute the function that should be stubbed

java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)

I am making some unit testing. but when i want to run that unit test it gave me error like this
"java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)"
what i am doing wrong?
this is my gradle. i wonder if i add wrong dependency into it, please help me :'(
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
multiDexEnabled true
applicationId "com.example.androidjetpacksubmission1"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug{
applicationIdSuffix ".debug"
debuggable true
}
}
testOptions {
unitTests.returnDefaultValues = true
}
androidExtensions {
experimental = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.github.bumptech.glide:glide:4.10.0'
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
implementation 'androidx.test.espresso:espresso-idling-resource:3.2.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
implementation 'com.facebook.shimmer:shimmer:0.5.0'
implementation "androidx.arch.core:core-testing:2.1.0"
implementation "org.mockito:mockito-android:3.1.0"
implementation 'androidx.multidex:multidex:2.0.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:core:1.2.0'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.ext:truth:1.2.0'
androidTestImplementation 'androidx.arch.core:core-testing:2.1.0'
androidTestImplementation 'com.google.truth:truth:0.42'
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:espresso-accessibility:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-web:3.2.0'
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.2.0'
androidTestImplementation 'com.android.support.test:runner'
androidTestImplementation group: 'org.mockito', name: 'mockito-core', version: '3.1.0'
androidTestImplementation group: 'org.mockito', name: 'mockito-inline', version: '3.1.0'
testImplementation "androidx.arch.core:core-testing:2.1.0"
androidTestImplementation "org.mockito:mockito-android:3.1.0"
androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
}
and this is my unit test code
package com.example.androidjetpacksubmission1.ui.detail
import androidx.lifecycle.Observer
import com.example.androidjetpacksubmission1.data.entity.TvShowEntity
import com.example.androidjetpacksubmission1.data.repository.RemoteRepository
import com.example.androidjetpacksubmission1.network.Network
import com.example.androidjetpacksubmission1.network.NetworkListener
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
class DetailTvShowViewModelTest : NetworkListener {
override fun onSuccess(msg: String) {
}
override fun onFailure(msg: String?) {
}
#get:Rule
var executorRule = androidx.arch.core.executor.testing.InstantTaskExecutorRule()
private lateinit var detailTvShowViewModel: DetailTvShowViewModel
private lateinit var remoteRepository: RemoteRepository
private lateinit var observer: Observer<*>
private val tvShowTitleExample = "Jumanji: The Next Level"
#Before
fun setup(){
observer = mock(Observer::class.java)
remoteRepository = RemoteRepository(Network.routes())
detailTvShowViewModel = DetailTvShowViewModel(remoteRepository,tvShowTitleExample)
detailTvShowViewModel.networkListener = this
}
#Test
fun getDetailMovie() {
detailTvShowViewModel.getDetailTvShow().observeForever(observer as Observer<in TvShowEntity>)
detailTvShowViewModel.fetchDetailTvShow()
verify(observer).onChanged()
}
}
private fun <T> Observer<T>.onChanged() {
}

MutableLiveData is null in JUnitTest

I want to write a unit test. Therefore I need MutableLiveData. I started with a very basic test for setup but I cannot instantiate a MutableLiveData object. I is always null when I run the test. Do I have to mock anything? Any suggestions?
#RunWith(MockitoJUnitRunner.class)
public class DefaultLiveDataTest {
private static final int EXPECTED = 5;
private final MutableLiveData<Integer> underTest = new MutableLiveData<>();
#Test
public void exampleTest() {
underTest.setValue(EXPECTED); //underTest is Null
assertEquals(underTest.getValue().intValue(), EXPECTED);
}
}
java.lang.NullPointerException
at android.arch.core.executor.DefaultTaskExecutor.isMainThread(DefaultTaskExecutor.java:58)
at android.arch.core.executor.ArchTaskExecutor.isMainThread(ArchTaskExecutor.java:116)
at android.arch.lifecycle.LiveData.assertMainThread(LiveData.java:434)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:279)
at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
at com.mypackage.DefaultLiveDataTest.test_that_live_data_has_default_value(DefaultLiveDataTest.java:22)
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId 'com.mypackage.title'
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName '1.0'
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
testOptions {
unitTests.returnDefaultValues = true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:support-vector-drawable:27.1.1'
implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'android.arch.lifecycle:viewmodel:1.1.1'
implementation 'android.arch.lifecycle:livedata:1.1.1'
annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.10.19'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
annotationProcessor 'org.androidannotations:androidannotations:4.4.0'
implementation 'org.androidannotations:androidannotations-api:4.4.0'
compileOnly 'org.projectlombok:lombok:1.16.20'
annotationProcessor 'org.projectlombok:lombok:1.16.20'
}
Looks like you are missing the android.arch.core:core-testing dependency.
testImplementation "android.arch.core:core-testing:1.1.1"
This allows you to use the InstantTaskExecutorRule in your test, which will get rid of the isMainThread call.
https://developer.android.com/reference/android/arch/core/executor/testing/InstantTaskExecutorRule.html
#Rule
public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule();
Add an executor InstantTaskExecutorRule() as a member of the Test class
A JUnit Test Rule that swaps the background executor used by the
Architecture Components with a different one which executes each task
synchronously. You can use this rule for your host side tests that use
Architecture Components.
//#RunWith(JUnit4::class) // For JUnit4
#ExtendWith(InstantExecutorExtension::class) // For JUnit5
class FilterViewModelTest {
#Rule #JvmField
val instantTaskExecutorRule = InstantTaskExecutorRule()
#Test
fun test() {
//Here you don't ask if isMainThread
}
}
build.gradle(:mobile)
android {
//...
dependencies {
//...
testImplementation 'androidx.arch.core:core-testing:2.1.0'
androidTestImplementation 'androidx.arch.core:core-testing:2.1.0'
}
}
GL
InstantTaskExecutorRule
I had this error and solved it by adding InstantTaskExecutorRule:
private lateinit var contactProfileViewModel: ContactProfileViewModel
private val getStatusesForContact: GetStatusesForContact = mockk(relaxed = true)
private val getStory: GetUserLastStory = mockk(relaxed = true)
private val successStatusesCaptor = slot<((List<StatusDomain>) -> Unit)>()
private val successStoryCaptor = slot<((List<StoryDomain>) -> Unit)>()
#get:Rule
val rule: TestRule = InstantTaskExecutorRule()
#Before
fun setUp(){
contactProfileViewModel = ContactProfileViewModel(getStatusesForContact, getStory)
}

Categories

Resources