KotlinでMockitoのany()
やisA()
を利用すると```java.lang.IllegalStateException: Mockito.any() must not be null
これらのメソッドがnullを返すため(プリミティブ型であればデフォルト値を返すのでこのエラーは起きません)で、Null安全なKotlinではエラーになります。
検証対象のメソッド引数をNullableにすれば当然解決しますが、それはやりたくないですよね。
例えば、以下の部分をモックにして引数を検証したいです。
```kotlin
transition.onNext(TransitionType.Success())
実際のコードとテストの検証時では別のインスタンスなので、同じクラスかどうか検証したいです。
なので、こう書きます。
Mockito.doNothing().`when`(mockEventBus).onNext(Mockito.isA(TransitionType.Success::class.java))
これだとエラーになります。
解決方法
以下のnullReturn()
のようにキャストすれば動作するようになりました。
class TestUtils private constructor() {
companion object {
fun <T> isA(type: Class<T>): T {
Mockito.isA<T>(type)
return nullReturn()
}
fun <T> any(): T {
Mockito.any<T>()
return nullReturn()
}
private fun <T> nullReturn(): T = null as T
}
}
Mockito.doNothing().`when`(mockEventBus).onNext(TestUtils.isA(TransitionType.Success::class.java))
理由はわかりませんが、Kotlinは null as String
のようにnullをキャストするとコンパイラーnullチェックを回避できます。
NotNullなクラスにキャストしているから、実際はnullでもNotNullとして判断されているのでしょうか。
(実行時にはTypeCastException
で落ちます。)
そして、何故かGenericsでのキャストでは実行時にも動作するのです。