UI 在 Jetpack Compose 中测试时未在 Box 上调用 LaunchedEffect
LaunchedEffect not called on Box while UI testing in Jetpack Compose
我是 运行 LaunchedEffect 的简单测试:
@Test
fun testSomeState() {
composeTestRule.setContent {
SomeComposable {
println("click $it")
}
}
composeTestRule.onNodeWithTag("Zivi")
.performClick()
.assertExists()
}
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Button(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}, onClick = { }) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
// and then "LaunchedEffect someState 2"
if (someState == 2) { onClick(someState) }
}
}
这很有效,但是,如果我将 Button 更改为 Box,如下所示:
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Box(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
if (someState == 2) { onClick(someState) }
}
}
然后在performClick上没有调用LaunchedEffect,谁能帮我理解为什么?
默认情况下可组合框没有任何大小,因此从技术上讲,当用户点击屏幕的任何部分时,事件不会被 Box
消耗。
您可以通过向框添加 background(color = Color.Green)
修饰符来验证这一点,并观察到屏幕上没有任何部分像预期的那样变成绿色。
您可以通过为 Box
.
设置 size
修饰符来解决此问题
您可以将您的框实现更改为此,它应该可以工作。我在这里使用fillMaxSize
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Box(modifier = Modifier
.fillMaxSize()
.testTag("Zivi")
.pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> {
1
}
MotionEvent.ACTION_UP -> {
2
}
else -> {
someState
}
}
true
}) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
// and then "LaunchedEffect someState 2"
if (someState == 2) {
onClick(someState)
}
}
}
我是 运行 LaunchedEffect 的简单测试:
@Test
fun testSomeState() {
composeTestRule.setContent {
SomeComposable {
println("click $it")
}
}
composeTestRule.onNodeWithTag("Zivi")
.performClick()
.assertExists()
}
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Button(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}, onClick = { }) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
// and then "LaunchedEffect someState 2"
if (someState == 2) { onClick(someState) }
}
}
这很有效,但是,如果我将 Button 更改为 Box,如下所示:
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Box(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
if (someState == 2) { onClick(someState) }
}
}
然后在performClick上没有调用LaunchedEffect,谁能帮我理解为什么?
默认情况下可组合框没有任何大小,因此从技术上讲,当用户点击屏幕的任何部分时,事件不会被 Box
消耗。
您可以通过向框添加 background(color = Color.Green)
修饰符来验证这一点,并观察到屏幕上没有任何部分像预期的那样变成绿色。
您可以通过为 Box
.
size
修饰符来解决此问题
您可以将您的框实现更改为此,它应该可以工作。我在这里使用fillMaxSize
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Box(modifier = Modifier
.fillMaxSize()
.testTag("Zivi")
.pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> {
1
}
MotionEvent.ACTION_UP -> {
2
}
else -> {
someState
}
}
true
}) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
// and then "LaunchedEffect someState 2"
if (someState == 2) {
onClick(someState)
}
}
}