以最简单的形式,我有这个对话框:
@Composable
fun MyDialog(
showDialogState: MutableState<Boolean>
) {
if (showDialogState.value) {
AlertDialog(onDismissRequest = { showDialogState.value = false },
// Other irrelevant attributes have been omitted
)
}
}
如何在 Robolectric 中的此可组合项上触发“onDismissRequest”?
这通常是我构建可组合测试的方式:
@Config(sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4::class)
@LooperMode(LooperMode.Mode.PAUSED)
class MyDialogTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun `MyDialog - when showing state and dismissed - changes showing state`() {
val state = mutableStateOf(true)
composeTestRule.setContent {
MyDialog(
showDialogState = state
)
}
// TODO: How do I trigger dismiss!?
assertFalse(state.value)
}
}
Compose 版本:1.1.0-rc01
Android Gradle 插件版本:7.0.4
Robolectric版本:4.7.3
我认为目前这是不可能的。我写了这个测试来确认:
val onButtonPressed = mock<() -> Unit>()
composeTestRule.setContent {
Scaffold(topBar = {
TopAppBar {
Text(text = "This test does not work")
}
}) {
AlertDialog(
onDismissRequest = {},
properties = DialogProperties(
dismissOnBackPress = true,
dismissOnClickOutside = true
),
title = { Text(text = "This is a dialog")},
confirmButton = { Button(onClick = {}) {
Text(text = "Confirm")
}}
)
Column(modifier = Modifier.fillMaxSize()) {
Spacer(modifier = Modifier.weight(1f))
Button(onClick = onButtonPressed) {
Text(text = "test")
}
}
}
}
composeTestRule.onNode(isDialog()).assertExists()
composeTestRule.onNodeWithText("test", ignoreCase = true).performClick()
verify(onButtonPressed).invoke()
composeTestRule.onNode(isDialog()).assertDoesNotExist()
即使按钮位于对话框“后面”,它也会接收单击事件而不关闭对话框。
手动测试已确认该实现有效,因此也许 UIAutomator 测试可以自动执行此操作,但这似乎是解决此问题的一种过于复杂的方法。
我引用官方文档:
当用户单击对话框外部或对话框上时关闭对话框 返回键。如果您想禁用该功能,只需使用 关闭请求时为空。
https://foso.github.io/Jetpack-Compose-Playground/material/alertdialog/
您可以按设备的后退按钮,这是关闭警报对话框的方法之一。
在我的测试中它看起来像这样:
composeRule.activity.onBackPressedDispatcher.onBackPressed()