protectedメソッドへのアクセス
Kotlinにおいてprotectedのアクセス修飾子は、Javaと異なり同一パッケージからのアクセスを許容しません。 そのため、テストコードなどでprotectedのメソッドを実行したい場合は、リフレクションを使う必要があります。
継承してテストするという方法もありそうですが、今までしなかった発想なのでどうなんですかね。
リフレクションによる実行
例えばTestDataRepositoryにcreateSampleDataというLongのパラメータを1つ取り、SampleDataクラスを返却するprotectedのメソッドあるとした場合、以下が対象のメソッドを実行するコードになっています。
var testSuite = TestDataRepository() val testMethod = testSuite::class.memberFunctions.find { it.name == "createSampleData" } val actual = testMethod?.let { it.isAccessible = true it.call(testSuite, 100L) }
コード解説
- まずは実行対象のメソッドがあるクラスのKClass(
testSuite::class)から、
KFunctionとして対象メソッドを取得(.memberFunctions.find { it.name == "createSampleData" })します - KFunctionのインスタンスが確保できていれば(
testMethod?.)、
呼び出し結果をactualに保持するようにします(val actual = testMethod?.let {) - 実行するためにアクセスを許可し(
it.isAccessible = true)、
実行するインスタンスとメソッドに与えるパラメータ(100L)を指定して実行します(it.call(testSuite, 100L))
以上になります。
protectedのテストが面倒になった?
Javaの場合はprotectedメソッドであれば同一パッケージからすんなり呼べたので、テストが楽でよかったのですが、Kotlinの場合はちょっと工夫がいりそうです。 もうちょっと簡単な方法もありそうなのですが(PowerMockのWhiteboxクラス使うとか)、おいおい調べてみないといけないなという感じです。