LoginSignup
10
5

More than 1 year has passed since last update.

Android UnitTestでR.stringのテストを劇的に見やすくする

Last updated at Posted at 2022-12-01

概要

Android で普通の Unit Test (Android Test/Instrument Test じゃない方のテスト) で R.string.xxx についての Assert を実行すると下記のような謎の数値のエラーになっちゃうんですよね。

テストコード
val actual = hoge.getTextId()
assertEquals(R.string.xxx, actual)

出力されるエラー:
image.png

こうだしたいですよね:

expected:<R.string.xxx> but was:<R.string.yyy>
Expected:R.string.xxx
Actual  :R.string.yyy
<Click to see difference>

java.jang ... (以下略)

ですが、AndroidTest でないと Resource にアクセスできないし、そもそもリソースのキー名は取れないし、ググっても方法見つからないし、難しい壁が立ちはだかってます。

ですが、方法あったんですね。
ReflectionR.string 解析してしまえばいいんです。
具体的に説明します。

用意するクラス

TestBase.kt
import kotlin.reflect.*

abstract class TestBase {

    fun assertResStringEquals(expected: Int, actual: Int) {
        assertEquals(getResStringName(expected), getResStringName(actual))
    }

    companion object {
        fun getResStringName(id: Int): String {
            return resStringId2Name[id] ?: "$id"
        }

        private val resStringId2Name: Map<Int, String> = R.string::class.members
            .filter { it.parameters.isEmpty() && it.visibility == KVisibility.PUBLIC }
            .associate {
                val name = it.name
                val id = it.call() as Int
                id to "R.string.$name"
            }
    }
}

これだけです。

テストクラス

実際のテストではこのように使います。

HogeTest.kt
class HogeTest : TestBase() {
    @Test
    fun hoge() {
        val actual = hoge.getTextId()
        assertResStringEquals(R.string.xxx, actual)  // ここを変えただけ
    }
}

これで理想通りにキーをベースにエラー出力されます!
簡単ですね!

10
5
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
10
5