我正在为 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")
}
您应该使用 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")
}