如何在Jetpack Compose测试中获取字符串资源?

10
我们可以通过stringResource在Composable中获取字符串资源,如下所示:
@Composable
fun Heading(
    @StringRes textResource: Int
) {
    Text(
        text = stringResource(id = textResource),
        color = colorBlack,
    )
}

但是我们如何在组合测试中获取此字符串资源。

class HeadingTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @ExperimentalComposeUiApi
    @Test
    fun headingTest() {
        // Start the app
        composeTestRule.setContent {
            AppTheme {
                // In Compose world
                Heading(textResource = R.string.some_text)
            }
        }

        //How can I access string resource here
        composeTestRule.onNodeWithText(???).assertExists()
    }
}
3个回答

14

您仍然可以使用 androidx.test.platform.app.InstrumentationRegistry 在Compose应用中获取资源。

    val context: Context = InstrumentationRegistry.getInstrumentation().getTargetContext()
    var string2 = context.resources.getString(R.string.hello_world)
    



我认为这是一个比目前所建议的方案更好的解决方案,因为它允许在任何特定活动之外隔离地测试组合件。仅有的一点评论是InstrumentationRegistry已被弃用。相反,您可以使用ApplicationProvider.getApplicationContext()来获取上下文。 - Shahar

5
通过createAndroidComposeRule创建组合规则,然后您将能够访问activity.getString()方法。
@get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()

val activity = composeTestRule.activity

@Test
fun testDisplayAndClickable() {
    val home = composeTestRule.activity.getString(R.string.home)
}

在此补充一点,如果您正在使用 createAndroidComposeRule<ComponentActivity>() 并从测试函数中设置其内容,例如 composeTestRule.setContent { },则 val activity 必须在设置内容后在函数内部声明。否则,您将会得到一个空指针异常。 - Jincy P Janardhanan
如果我们正在使用模块,而且在我们的模块中没有任何活动会怎么样? - Daniyal Javaid
由于某种原因,会产生“java.lang.NullPointerException:Cannot run onActivity since Activity has been destroyed already”的错误。也许是因为我的测试中还有另一条规则与之冲突?即 @get:Rule val composeTestRule = createComposeRule() - Kurovsky

4

我不确定是否有更好的方法,但你可以按照以下步骤进行:

class HeadingTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @ExperimentalComposeUiApi
    @Test
    fun headingTest() {
        val textId = R.string.some_text
        var string = ""
        // Start the app
        composeTestRule.setContent {
            string = stringResource(id = textId)
            AppTheme {
                // In Compose world
                Heading(textResource = textId)
            }
        }
        composeTestRule.onNodeWithText(string).assertExists()
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接