ArgumentMatchers.any must not be null

22,565

Solution 1

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?

Solution 2

The correct solution is mentioned in the comment section of the question by @Ana Koridze. Yes, if you are using Koltin + mockitoKotlin. Make sure you are using the following import:

1 - Using the Mockito-kotlin:

import org.mockito.kotlin.any from Mockito-kotlin instead of import org.mockito.Mockito.any

testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"

2 - Or if you are using older mockito kotlin version original created by nhaarman before the intergation

import com.nhaarman.mockitokotlin2.any from nhaaram's Mockito-kotlin instead of import org.mockito.Mockito.any

testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$mockito_kotlin2_version"

BTW, if you are using Android Studio or IntelliJ IDEA. the any() from mockitokotlin library should be italic by default style/color scheme.


Notice the any() at the end of line. This is from mockitokotlin

enter image description here

And here is the any() from mockito

enter image description here

Thanks @Sattar for the recommended edit.

Solution 3

mockito-kotlin has added support for nullable args with anyOrNull()

        `when`(myMock.doesThis(any(), anyOrNull())).thenReturn(someObject)

Solution 4

use Mockito-kotlin

testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"

this will use any that works for kotlin as this is a wrapper lib for Mockito but for kotlin

Solution 5

For me all solutions above were not enough - in addition to that I had to mark the called method as an 'open' method. According to this: https://github.com/mockito/mockito-kotlin/wiki/Parameter-specified-as-non-null-is-null The method is final and Mockito couldn't mock it so I had to add 'open'.

Share:
22,565
Ana Koridze
Author by

Ana Koridze

Updated on July 09, 2022

Comments

  • Ana Koridze
    Ana Koridze almost 2 years

    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.

  • Nouman Ch
    Nouman Ch about 3 years
    the only thing worked for me. Thanks @Haomin
  • MarounG
    MarounG over 2 years
    I had the same problem and then read your answer and checked my imports and now it works! Thanks!
  • orpheus
    orpheus over 2 years
    Thank you very much for this explanation and these answers. The first typed class fn worked for me perfectly.
  • Arkady
    Arkady over 2 years
    You saved my day. Thanks!