1

I have a simple test class

class SimpleClassTest {

    private fun <T> anyObject(): T {
        return Mockito.anyObject<T>()
    }

    lateinit var simpleObject: SimpleClass
    @Mock lateinit var injectedObject: InjectedClass


    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
    }

    @Test
    fun testSimpleFunction() {
        simpleObject = SimpleClass(injectedObject)
        simpleObject.simpleFunction()

        verify(injectedObject).settingDependentObject(anyObject())
    }
}

It works fine and pass.

Since the private generic anyObject() function is only used once, so I decide to inlining it (manually) i.e. remove the need of that function, whereby I change from

verify(injectedObject).settingDependentObject(anyObject())

to

verify(injectedObject).settingDependentObject(Mockito.anyObject<DependentClass>())

However this now error as java.lang.IllegalStateException: Mockito.anyObject<DependentClass>() must not be null

Anything I did wrong inlining the function call to a direct statement?

Is there anything different between using

private fun <T> anyObject(): T {
    return Mockito.anyObject<T>()
}

and the below?

Mockito.anyObject<DependentClass>()
Elye
  • 53,639
  • 54
  • 212
  • 474

1 Answers1

5

The source for Mockito.anyObject():

/**
 * Matches anything, including null.
 * <p>
 * This is an alias of: {@link #any()} and {@link #any(java.lang.Class)}
 * <p>
 * See examples in javadoc for {@link Matchers} class
 * 
 * @return <code>null</code>.
 */
public static <T> T anyObject() {
    return (T) reportMatcher(Any.ANY).returnNull();
}

This method sets some internal state for Mockito, and then proceeds to return null. Since you're expecting a non-null instance in your settingDependentObject() method, the runtime fails.


Why your first method succeeded, however, I'm not sure. Casting null to T seemed to work a while ago, but it doesn't work for me anymore. For that matter, I can't get your first implementation to succeed either.

Community
  • 1
  • 1
nhaarman
  • 98,571
  • 55
  • 246
  • 278
  • 1
    To overcome this problem, I wrote a little [helper library](https://www.github.com/nhaarman/mockito-kotlin). – nhaarman May 22 '16 at 17:02
  • Hi @nhaarman, great to hear from you. Actually I'm aware of the null error issue due to Kotlin null-safe requirement, and Mockito returning null, and were wondering how that function got it working for me. Hence I post my question up as it is. I did try to use the helper library, but there's an issue when using a OkHttp response. I post the question at http://stackoverflow.com/questions/37380830/java-lang-reflect-invocationtargetexception-when-using-kotlin-mokito-library, which is specifically for you. (I think others will not be able to answer it, as it might be your library specific). Thanks – Elye May 22 '16 at 23:57
  • 2
    @nhaarman The first method works because the compiler doesn't insert a null check after calling `SimpleClassTest.anyObject` function. This behavior may be changed later, see [KT-8135](https://youtrack.jetbrains.com/issue/KT-8135) – Ilya May 23 '16 at 01:27
  • @llya, thanks for pointing this out. Perhaps you could put the comment as answer, explaining why one compiles and the other doesn't, that I could give a tick to it. As I plan to tick answer that covers both scenario. – Elye May 23 '16 at 08:21