首页 > 解决方案 > 使用带有嵌套 NavHostFragments 的 FragmentScenario 会使某些导航在测试期间无法验证

问题描述

在我的应用程序中,我有一个包含 NavHostFragment 的 MainActivity。那NavHostFragment是用来展示Fragment的,其中一些有自己的NavHostFragment。

例如,MainActivity 持有 NavHostFragment1,它指向默认显示 FragmentA 的 main_nav_graph.xml。用户与 Fragment A 交互以启动包含 NavHostFragment2 的 MasterDetailFragment。

所以 main_nav_graph.xml 看起来像: FragmentA -> MasterDetailFragment

当用户在 MasterDetailFragment 中并单击后退按钮时,我们拦截后按并向用户显示 CancelConfirmationFragment。如果用户确认他们想要离开屏幕,那么我们需要执行导航回到 FragmentA。这是它变得有点棘手的地方。

如果我只是盲目地使用 CancelConfirmationFragment 中的 findNavController() 函数,那么它将获得嵌套的 NavHostFragment (NavHostFragment2) 的句柄并尝试使用它执行导航,这将是不正确的。我真正需要的是在 MainActivity 中获取 NavHostFragment1 的句柄。为此,我创建了一个 MainActivity 实现的接口,该接口在调用时返回 MainActivity 的 NavHostFragment。

// This gets a handle to MainActivity's navController
(requireActivity() as HasNavController).getNavController().popBackStack(R.id.fragment_a, false)

当我手动测试我的应用程序时,效果很好。但是,当我单独在 MasterDetailFragment 上运行 Instrumentation 测试时,我遇到了一个问题,因为我实际上没有 MainActivity 的实例来保存我的 MasterDetailFragment,我有一个 FragmentScenario 创建的 Activity 实例,它没有实现我的特殊接口。

为了让我的仪器测试正常工作,我停止使用 FragmentScenario 并专门为名为 FakeMainActivity 的测试创建一个 Activity。FakeMainActivity 将有一个 NavHostFragment 并将实现 MainActivity 实现的特殊接口。在测试设置中,我可以将一个模拟导航控制器传递给 FakeMainActivity 并验证当用户确认他们想要导航回模拟导航控制器是否已对其进行了特定调用时。这似乎是一个不错的解决方案,但是,我觉得我可以通过任何导航目的地(即使是无法到达的)并且测试会通过,但实际上它不会,所以我什至不确定测试是否真的很值得写。

我是否从根本上错误地使用了导航组件或 FragmentScenario?

一般来说,这只是一件很难测试的事情吗?

我是否应该在非隔离测试(如 e2e 测试或两个片段之间的集成测试)中测试这样的导航(从一个导航主机移动到另一个)?

如果 FragmentScenario 可以接受允许由它启动自定义 Activity 而不是 FragmentScenario 提供的 Activity 的参数,这是否有意义?

标签: androidandroid-fragmentsandroid-architecture-navigationandroid-fragmentscenario

解决方案


推荐阅读