MockKでモックオブジェクトが生成できない条件

MockKでString型のモックオブジェクトを生成しようとしたところ、以下のエラーが発生しました。

io.mockk.MockKException: Can't instantiate proxy for class kotlin.String

String型のモックオブジェクトが生成できないことを知らなかったので、スタックトレースを辿ったところ、

io.mockk.proxy.MockKAgentException: Failed to create proxy for class java.lang.String.
class java.lang.String is one of excluded classes
at io.mockk.proxy.jvm.ProxyMaker.throwIfNotPossibleToProxy

とあり、String型のモックオブジェクトを生成する過程で、ProxyMaker#throwIfNotPossibleToProxy()内でMockKAgentExceptionがthrowされていました。

ProxyMaker#throwIfNotPossibleToProxy()の処理内容を整理すると、以下のいずれかの条件を満たすときにモックオブジェクトが生成できないことが分かりました。

  • 1.モック対象のオブジェクトが以下のいずれかの型である
    • プリミティブ型 および それらのラッパークラス
    • String型
    • Void型
    • Class型
  • 2.モック対象のオブジェクトが任意の型の配列である
  • 3.モック対象のオブジェクトが以下のすべての条件を満たす
    • 1.finalクラスのオブジェクトである
    • 2.@MockKアノテーションによってフィールドインジェクションされる
    • 3.インジェクション先のフィールドに@AdditionalInterfaceアノテーションが指定されている

最後の条件が少し分かりづらいですが、以下のようなコードを書くとMockKAnnotations.init(this)の時点でMockKAgentExceptionがthrowされます。

import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.AdditionalInterface
import io.mockk.impl.annotations.MockK
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class SampleClass {
  fun hoge(): String = "hoge"
}

interface SampleInterface {
  fun fuga(): String
}

class SampleTest {

  @MockK
  @AdditionalInterface(SampleInterface::class)
  private lateinit var sample: SampleClass

  @BeforeEach
  fun beforeEach() {
    MockKAnnotations.init(this)
  }

  @Test
  fun test() {
    every { sample.hoge() } returns "[override] hoge"
    every { (sample as SampleInterface).fuga() } returns "[implementation] fuga"

    ...

  }

}

参考