我有两个片段,其中一个是我图中的主片段。单击按钮后,用户将导航到第二个片段。它按预期工作,将用户导航到第二个片段并显示文本。所以图表很好。
现在我想编写一个仪器测试。
@RunWith(AndroidJUnit4::class)
class TransitionTest {
@Test
fun testNavigationToSecondFragment() {
val navController = TestNavHostController(
ApplicationProvider.getApplicationContext())
navController.setGraph(R.navigation.my_graph) <--throws exception
// the rest of my test continues here
}
}
但是,上面显示的用于设置图表的行会引发以下异常:
IllegalStateException:必须在 main 上调用方法 addObserver 线程。
我的环境:
fragment_version = 1.2.5 nav_version = 2.3.1 espresso = 3.3.0
有人知道发生了什么事以及如何解决吗?
我将
setGraph
函数包装在 runOnUiThread
中,测试通过了。一旦找到真正的原因和更好的解决方案,我会更新答案。
runOnUiThread {
navController.setGraph(R.navigation.my_graph)
}
我也遇到了同样的问题,所以我会尝试解释其根本原因。 从
androidx.lifecycle:lifecycle-*:2.3.0-alpha06
开始。 LifecycleRegistry
的行为发生了变化。 LifecycleRegistry
现在验证其方法是否在主线程上调用。现在还有另一个未解决的问题:仪器测试是否在主线程中运行?显然没有,否则它就会过去。它使用 Instrumentation Thread 来运行大多数测试。根据文档,您可以使用 @UiThreadTest
或 runOnUiThread
,如顶部的 answer。
还有另一种解决方案可以使用此解决方案
InstrumentationRegistry.getInstrumentation().runOnMainSync {
navController.setGraph(R.navigation.my_graph)
}
由于
@UiThreadTest
仅适用于 @Test
、@Before
和 @After
,因此如果您有一些常见的测试功能,它们可能无法按预期工作
当我的 com.google.gms:google-services 库与 appcompat 版本冲突时,我遇到了这个问题。当我将 appcompat 版本更改为以下版本时,问题得到解决
implementation 'androidx.appcompat:appcompat:1.3.0'
当我尝试从 ViewModel (视图模型类)导航到其他屏幕时,我遇到了同样的问题。当我使用 viewModelScope.launch 进行导航时,问题得到了解决
例如。
viewModelScope.launch {
navController.navigate(Route.LOGIN_SCREEN)
}