Android returns 颜色资源 id 来自 R.attr 参考的测试方法

Android Testing method that returns color resource id from R.attr reference

我第一次使用 Android Studio 3.2 实现 AndroidInstrumentationTest,尝试检查方法 returns 颜色资源 ID 是否来自属性(R.attr 和颜色在样式中设置)取决于字符串,但返回的资源 ID 始终为 0 而不是预期的。

代码在我的应用程序中运行正常,颜色设置如下:

textView.setTextColor(fetchCorrectColor(myContext))

问题是来自测试的 fetchColor returns 0

其他资源 mContext.getString() 完美运行

Test class 在 Android Pie (28) 模拟和设备上用 @RunWith(AndroidJunit4::class) 和 运行 注释

我尝试了不同的上下文但结果相同:

InstrumentationRegistry.getInstrumentation().targetContext
InstrumentationRegistry.getInstrumentation().context
ApplicationProvider.getApplicationContext()

测试方法

fun getTextColor(status: String?, mContext: Context): Int{
    return when(status){
        "A", "B" ->{
            fetchCorrectColor(mContext)
        }
        "C", "D"->{
            fetchWarningColor(mContext)
        }
        else -> {
            fetchDisabledColor(mContext)
        }
    }
}

如果从属性获取颜色资源的方法

fun fetchCorrectColor(context: Context): Int{
    return fetchColor(context, R.attr.correct)
}

private fun fetchColor(context: Context, colorId: Int): Int{
    val typedValue = TypedValue()
    context.theme.resolveAttribute(colorId, typedValue, true)
    return typedValue.data
}

测试

@Test fun getTextColor_isCorrect(){
    Assert.assertEquals(R.attr.correct, getTextColor("A", mContext))
    Assert.assertEquals(R.attr.correct, getTextColor("B", mContext))
    Assert.assertEquals(R.attr.warning, getTextColor("C", mContext))
    Assert.assertEquals(R.attr.warning, getTextColor("D", mContext))
    Assert.assertEquals(R.attr.disabled, getTextColor(null, mContext))
}

这是我一直遇到的错误:

java.lang.AssertionError: expected:<2130968760> but was:<0>
at org.junit.Assert.fail(Assert.java:88)

属性是 Theme 感知的。确保 context 使用与您的应用相同的 theme

appContext.setTheme(R.style.AppTheme)

示例测试代码解析仅在 AppCompat 主题中可用的 R.attr.colorPrimary 属性:

@Test
fun testColorPrimary() {
    // Context of the app under test.
    val appContext = InstrumentationRegistry.getTargetContext()

    // actual R.color.colorPrimary value
    val actualPrimaryColor = appContext.getColor(R.color.colorPrimary)

    // R.attr.colorPrimary resolved with invalid theme
    val colorPrimary1 = TypedValue().also {
        appContext.theme.resolveAttribute(R.attr.colorPrimary, it, true)
    }.data

    // provided context has invalid theme so attribute resolution fails (returns 0)
    assertEquals(0, colorPrimary1)

    // be sure test context uses same theme as app
    appContext.setTheme(R.style.AppTheme)

    // R.attr.colorPrimary resolved from valid theme
    val colorPrimary2 = TypedValue().also {
        appContext.theme.resolveAttribute(R.attr.colorPrimary, it, true)
    }.data

    // valid theme returns proper color
    assertEquals(actualPrimaryColor, colorPrimary2)
}