在测试中更改配置时,Composable 不记得输入

问题描述 投票:0回答:1

我正在为 Jetpack Compose 组件编写仪器测试。我的可组合项使用

rememberSaveable
来记住配置更改(活动重新启动):

@Composable
fun AddUserScreen() {
    Input(
        shouldRequestFocus = true,
        stringResource(R.string.user_first_name),
        stringResource(R.string.user_first_name_label),
        tag = "input-first-name"
    )
}

@Composable
fun Input(
    shouldRequestFocus: Boolean,
    text: String,
    label: String,
    tag: String
) {
    var value by rememberSaveable { mutableStateOf("") } // <-- Important part
    val focusRequester = FocusRequester()

    Row(verticalAlignment = Alignment.CenterVertically) {
        Text(text)
        Spacer(modifier = Modifier.width(10.dp))
        TextField(
            value = value,
            onValueChange = { value = it },
            label = { Text(label) },
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
            modifier = Modifier
                .focusRequester(focusRequester)
                .testTag(tag)
        )
    }

    if (shouldRequestFocus) {
        DisposableEffect(Unit) {
            focusRequester.requestFocus()
            onDispose { }
        }
    }
}

当我自己打开应用程序并旋转设备时,输入值将被保留。但在下面的测试中,配置更改时不会保留输入,测试失败:

@get:Rule val composeTestRule = createAndroidComposeRule<AddUserActivity>()

@Test fun whenAConfigChangeHappensTheFirstNameInputShouldRetainItsValue() {
    composeTestRule.setContent {
        WorkoutLoggerTheme {
            AddUserScreen()
        }
    }
    composeTestRule.onNodeWithTag("input-first-name").performTextInput("John")
    composeTestRule.activity.requestedOrientation = SCREEN_ORIENTATION_LANDSCAPE
    composeTestRule.waitForIdle()
    composeTestRule.onNodeWithTag("input-first-name").assertTextEquals("John")
}
android android-jetpack-compose ui-testing instrumented-test composable
1个回答
0
投票

您应该使用 StateRestorationTester 类来模拟可组合项的重新创建,而不是实际更改方向。你想要这样的东西:

@get:Rule val composeTestRule = createAndroidComposeRule<AddUserActivity>()

@Test fun whenAConfigChangeHappensTheFirstNameInputShouldRetainItsValue() {
    val restorationTester = StateRestorationTester(composeTestRule)

    restorationTester.setContent {
        WorkoutLoggerTheme {
            AddUserScreen()
        }
    }

    composeTestRule.onNodeWithTag("input-first-name").performTextInput("John")

    restorationTester.emulateSavedInstanceStateRestore()

    composeTestRule.onNodeWithTag("input-first-name").assertTextEquals("John")
}

一些链接:官方文档相关媒体文章

© www.soinside.com 2019 - 2024. All rights reserved.