The test class below, pass.
class SimpleClassTest {
private inline fun <reified 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())
}
}
But if we change from
private inline fun <reified T> anyObject(): T {
return Mockito.anyObject<T>()
}
to
private inline fun <reified T: Any> anyObject(): T {
return Mockito.anyObject<T>()
}
It will fail with
java.lang.IllegalStateException: Mockito.anyObject<T>() must not be null
What's the different of <reified T>
with <reified T: Any>
in Kotlin?
UPDATED
With the answer that Any is non-null, then using <reified T: Any>
shouldn't return error, since settingDependentObject(...)
is declared receiving a non-null argument. I would expect <reified T>
should error out instead, but it's opposite from what I understand.
Did I understand something wrong?
As stated in the documentation and the linked answer the default upper bound is Any?
. In other words the following declarations are equivalent:
inline fun <reified T> anyObject(): T = Mockito.anyObject<T>()
inline fun <reified T:Any?> anyObject(): T = Mockito.anyObject<T>()
The Mockito.anyObject<T>()
will return null
for both T:Any
and T:Any?
. When the method with return type T:Any
is invoked the null
value returned by Mockito fails the runtime check inserted by Kotlin compiler. The error you're getting is thrown before settingDependentObject
is invoked.
When you add T : Any
constraint on a type parameter, you're making it effectively non-null: T
is subtype of Any
and Any
can't hold nulls.
Since the function is inline and has a reified type parameter, that parameter gets substituted with a real non-nullable type. And thus a null-check is performed on a call site, so you're getting this exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With