mockito / mockito-kotlin

Using Mockito with Kotlin
MIT License
3.09k stars 198 forks source link

Exception in thread “main @coroutine#2” java.lang.NullPointerException in ViewModelTest? #436

Closed kyodgorbek closed 3 years ago

kyodgorbek commented 3 years ago

I have implemented I have implemented unit testing in ViewModel with mockito. class but I am getting following exception

Exception in thread "main @coroutine#2" java.lang.NullPointerException at com.example.giphyandroidapp.viewmodel.GiphyTaskViewModel$getGifsFromText$1.invokeSuspend(GiphyTaskViewModel.kt:24) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.test.TestCoroutineDispatcher.dispatch(TestCoroutineDispatcher.kt:50) at kotlinx.coroutines.test.internal.TestMainDispatcher.dispatch(MainTestDispatcher.kt:35) at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:305) at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30) at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:27) at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110) at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158) at kotlinx.coroutines.BuildersKtBuilders_commonKt.launch(Builders.common.kt:56) at kotlinx.coroutines.BuildersKt.launch(Unknown Source) at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:49) at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source) at com.example.giphyandroidapp.viewmodel.GiphyTaskViewModel.getGifsFromText(GiphyTaskViewModel.kt:22) at com.example.giphyandroidapp.viewmodel.GiphyTaskViewModelTest$onCreation_fetchUserApiCalled_dataSavedToLiveData$1.invokeSuspend(GiphyTaskViewModelTest.kt:61) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274) at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:84) at kotlinx.coroutines.BuildersKtBuildersKt.runBlocking(Builders.kt:59) at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38) at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source) at com.example.giphyandroidapp.viewmodel.GiphyTaskViewModelTest.onCreation_fetchUserApiCalled_dataSavedToLiveData(GiphyTaskViewModelTest.kt:57) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod

my ViewModel class where I have implemented viewmodel logic

@HiltViewModel class GiphyTaskViewModel @Inject constructor(private val giphyTaskRepository: GiphyTaskRepository):ViewModel() { var giphyresponse=MutableLiveData<List>()

fun getGifsFromText(apikey:String,text:String,limit:Int)= viewModelScope.launch {
    giphyTaskRepository.getGifsFromText(apikey,text,limit).let { response->
        if(response.isSuccessful){
            var list=response.body()?.data
            giphyresponse.postValue(list)
        }else{
            Log.d("TAG", "getGifsFromText: ${response.message()}");
        }

    }
}

}

below Repository class

class GiphyTaskRepository @Inject constructor(private val giphyTaskApiService: GiphyTaskApiService) {

suspend fun getGifsFromText(apikey:String,text:String,limit:Int)=
    giphyTaskApiService.getGifsFromText(apikey,text,limit)

}

below interface class

interface GiphyTaskApiService {

    @GET("gifs/search")
    suspend fun getGifsFromText(
        @Query("api_key") api_key:String,
        @Query("q") q:String ,
        @Query("limit") limit:Int
    ):Response<GiphyResponse>
}

below my ViewModel test class

@ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) class GiphyTaskViewModelTest {

    @Mock
    private lateinit var apiUsersObserver: Observer<List<DataItem>>

    @RegisterExtension
    @JvmField
    @get:Rule
    val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()

    @get:Rule
   val testCoroutineRule = TestCoroutineRule()
    @Mock
    lateinit var giphyTaskViewModel:GiphyTaskViewModel

    @Mock
     lateinit var  giphyTaskRepository:GiphyTaskRepository

    @Before
    fun setUp() {
          giphyTaskViewModel = GiphyTaskViewModel(giphyTaskRepository)
        }

    @Test
    fun onCreation_fetchUserApiCalled_dataSavedToLiveData() {
        runBlocking {

             giphyTaskViewModel.getGifsFromText("WGFWtAdbnXbmeY3fSY2x9VkFXohNBJHd", "q", 1)
            verify(giphyTaskRepository).getGifsFromText("WGFWtAdbnXbmeY3fSY2x9VkFXohNBJHd", "q", 1)
            giphyTaskViewModel.giphyresponse.observeForever(apiUsersObserver)
            assertNotNull(giphyTaskViewModel.giphyresponse.value)

        }
    }

}

I want to know where exactly I am making mistake what I have to inorder to pass the tests