Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArgumentMatchers.any must not be null

I am trying to test ViewModel to make sure livedata gets updated correctly. However when using ArgumentMatchers.any() it fails with IllegalStateException saying:

ArgumentMatchers.any(mViewModel.CountSubscriber::class.java) must not be null

@Test fun emitValueIfCountIs7() {     doAnswer { invocation: InvocationOnMock ->         val subscriber: mViewModel.CountSubscriber = invocation.getArgument(0)         subscriber.onNext(7)         null     }.`when`(countUseCase).execute(         ArgumentMatchers.any(mViewModel.CountSubscriber::class.java),         ArgumentMatchers.any(Parameters::class.java)     )          // When     mViewModel.getCount()          // Verify     assert(mViewModel.countResponse.value != null) } 

I am using Kotlin and have the following dependencies:

testImplementation 'junit:junit:4.12' testImplementation "org.mockito:mockito-inline:2.23.4" testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0" 

Here are my imports:

import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.nhaarman.mockitokotlin2.doAnswer import io.reactivex.Observable import org.junit.Before import org.junit.Rule import org.junit.Test import org.mockito.ArgumentMatchers.any import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations import org.mockito.invocation.InvocationOnMock 

Strange thing is that it used to work before, and I don't know what has happened that could affect this.

like image 726
Ana Koridze Avatar asked Dec 07 '19 20:12

Ana Koridze


People also ask

Does any() in Mockito include null?

Since Mockito any(Class) and anyInt family matchers perform a type check, thus they won't match null arguments. Instead use the isNull matcher.

Does anyString include Null?

anyString() does not work for null · Issue #185 · mockito/mockito · GitHub.

What is EQ Mockito?

Mockito Argument Matcher - eq() When we use argument matchers, then all the arguments should use matchers. If we want to use a specific value for an argument, then we can use eq() method. when(mockFoo. bool(eq("false"), anyInt(), any(Object. class))).


1 Answers

Getting matchers to work with Kotlin can be a problem. If you have a method written in kotlin that does not take a nullable parameter, then we cannot match with it using Mockito.any(). This is because it can return void and this is not assignable to a non-nullable parameter.

If the method being matched is written in Java, then I think that it will work as all Java objects are implicitly nullable.

One possible solution would be to use a library like mockito-kotlin But you can solve this issue easily with a few lines of code yourself.

If you need typed any(type: Class)

private fun <T> any(type: Class<T>): T = Mockito.any<T>(type) 

OR

You can use this matcher instead of Matchers.any() :

object MockitoHelper { fun <T> anyObject(): T {     Mockito.any<T>()     return uninitialized() } @Suppress("UNCHECKED_CAST")    fun <T> uninitialized(): T =  null as T } 

and use MockitoHelper.anyObject() instead of any() in your kotlin tests.

You can find more information in this post: Using Mockito with Kotlin

There is a discussion about possible solutions in this post : Is it possible to use Mockito in Kotlin?

like image 66
Nabzi Avatar answered Sep 20 '22 03:09

Nabzi