我创建了一个LoginFragment,当使用Navigation Architecture组件成功登录时,该导航可以导航到另一个。工作正常,但测试失败。它与GithubBrowser示例非常相似,我的测试与clickRepo
测试here非常相似,不同之处在于,我正在测试发布成功资源而不是在成功发布资源时加载新页面。点击。
错误:
Wanted but not invoked:
navController.navigate(
app.ui.login.LoginFragmentDirections$ShowSelectMerchant@377f3c27
);
LoginFragmentTest.kt
@Test
fun success(){
val user = TestUtil.createUser(email)
userData.postValue(Resource.success(user))
System.out.println("Test NavController Hash: " + testFragment.navController.hashCode())
verify(testFragment.navController).navigate(LoginFragmentDirections.showSelectMerchant().matcher())
}
LoginFragment.kt
override fun openSelectMerchantFragment() {
System.out.println("Real NavController Hash: " + navController().hashCode())
navController().navigate(LoginFragmentDirections.showSelectMerchant())
}
将成功的资源发布到实时userData时,将调用 openSelectMerchantFragment
。测试失败有明显的原因吗?
我可以看到测试片段的模拟的nav控制器和在片段本身中被调用的控制器具有相同的哈希值,因此我很确定我模拟活动,片段或nav控制器的方式没有问题。我也可以很明显地看到,确实调用了navigation()函数。
答案 0 :(得分:0)
这里的问题是Ian所建议的测试LiveData的简单问题。添加TaskExecutorWithIdlingResourceRule
是不够的,但是必须调用drainTasks()
才能完成数据发布。我无法回答为什么它在没有调用drainTasks
的情况下就可以在示例的整个测试类中起作用,我最好的猜测是,这些测试中的发布速度足够快,以至于不会成为问题。我认为是一个好习惯,每当发布实时数据时始终调用drainTasks
。
最终结果:
@Test
fun success(){
val user = TestUtil.createUser(email)
userData.postValue(Resource.success(user))
executorRule.drainTasks(1, TimeUnit.SECONDS)
verify(testFragment.navController).navigate(LoginFragmentDirections.showSelectMerchant().matcher())
}