17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

KotlinでMockitoのany()などのArgumentMatchersを使う方法

Last updated at Posted at 2017-11-09

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でのキャストでは実行時にも動作するのです。

17
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?