Navigation のコードをコンポーザブルのデスティネーションから分離して、NavHost
コンポーザブルとは別に、各コンポーザブルを個別にテストできるようにします。
NavController をコンポーザブルに直接渡さないでください。代わりに、ナビゲーション コールバック(ラムダ)をパラメータとして渡します。これにより、テストで
NavController のインスタンスが不要になるため、すべてのコンポーザブルを個別にテストできます。
NavHost の composable ラムダは、Navigation API とコンポーザブルの橋渡しとして機能します。
@Composable
fun ProfileScreen(
userId: String,
navigateToFriendProfile: (friendUserId: String) -> Unit
) {
// …
}
// In your NavHost
composable<Profile> { backStackEntry ->
val profile = backStackEntry.toRoute<Profile>()
ProfileScreen(userId = profile.id) { friendUserId ->
navController.navigate(route = Profile(id = friendUserId))
}
}
このように、モック値とコールバックを渡すことで、Navigation とは独立して ProfileScreen をテストできます。
NavHost、コンポーザブルに渡されるナビゲーション アクション、個々の画面コンポーザブルをテストすることにより、アプリ
ナビゲーションの要件に対応するテストを作成することをおすすめします。
NavHost をテストする
NavHost のテストを開始するには、アプリ モジュールの build.gradle ファイルに次の navigation-testing
の依存関係を追加します。
dependencies {
androidTestImplementation "androidx.navigation:navigation-testing:$navigationVersion"
}
アプリの NavHost を、
NavHostController をパラメータとして受け取るコンポーザブルでラップします。
@Composable
fun AppNavHost(navController: NavHostController){
NavHost(navController = navController, startDestination = Home){
composable<Home> { /*...*/ }
composable<Profile> { /*...*/ }
}
}
これで、AppNavHost と NavHost
ナビゲーション テスト アーティファクト
TestNavHostController のインスタンスを渡すことで、内部で定義されたナビゲーション ロジックをテストできます。
アプリの開始デスティネーションと NavHost を検証する UI テストは次のようになります。
class NavigationTest {
@get:Rule
val composeTestRule = createComposeRule()
lateinit var navController: TestNavHostController
@Before
fun setupAppNavHost() {
composeTestRule.setContent {
navController = TestNavHostController(LocalContext.current)
navController.navigatorProvider.addNavigator(ComposeNavigator())
AppNavHost(navController = navController)
}
}
@Test
fun appNavHost_verifyStartDestination() {
composeTestRule
.onNodeWithContentDescription("Start Screen")
.assertIsDisplayed()
}
}
ナビゲーション アクションをテストする
ナビゲーションの実装は複数の方法でテストできます。UI 要素をクリックして表示されたデスティネーションを検証する方法や、想定されるルートと現在のルートを比較する方法があります。
具体的なアプリの実装をテストする場合は、UI をクリックすることをおすすめします。このテスト方法と、個々のコンポーズ可能な関数を個別にテストする方法については、Jetpack Compose でのテスト Codelab をご覧ください。
navController を使用して、currentBackStackEntry を使用して現在のルートと想定されるルートを比較することで、ナビゲーション
アサーションを確認することもできます。
@Test
fun appNavHost_clickProfile_navigatesToProfile() {
composeTestRule.onNodeWithContentDescription("Go to Profile")
.performClick()
assertTrue(navController.currentBackStackEntry?.destination?.hasRoute<Profile>() ?: false)
}
Compose のテストの基本の詳細については、 Compose レイアウトのテストガイドをご覧ください。