【发布时间】:2018-06-19 04:32:03
【问题描述】:
我的应用程序发生崩溃,有时会在活动生命周期后调用 dialog.show。我知道这发生在哪里,并且想对应用程序中发生的每个错误进行单元测试,以避免它再次出现。但是如何才能对这样的东西进行(单元?)测试呢?
【问题讨论】:
-
您的意思是如何使用单元测试来测试这些东西?
标签: android unit-testing testing
我的应用程序发生崩溃,有时会在活动生命周期后调用 dialog.show。我知道这发生在哪里,并且想对应用程序中发生的每个错误进行单元测试,以避免它再次出现。但是如何才能对这样的东西进行(单元?)测试呢?
【问题讨论】:
标签: android unit-testing testing
很难对异常进行单元测试,因为正如异常消息所暗示的那样,事件与 Activity 生命周期紧密相关 - 事件的隔离实际上是不可能的。
您可以使用Robolectric 并尝试验证在onSaveInstanceState 调用之前是否调用了dialog.show() 方法,但我不会以这种方式解决问题。并且使用 Robolectric 的测试不再是单元测试。
我遇到了一些消除异常发生的解决方案:
FragmentTransaction 相关的方法执行,并在尝试执行show() 方法时识别活动是否调用了onSaveInstanceState。
如果活动处于created/started/resumed 状态,您可以立即执行show()。如果没有,则存储延迟 show() 执行的函数并执行它们下面几行伪代码:
if (isCreatedOrStartedOrResumed) {
dialog.show()
} else {
internalQueue.add {
dialog.show()
}
}
活动是否返回resumed状态,执行所有待处理函数
fun onResume() {
super.onResume()
while(internalQueue.isNotEmpty()) {
internalQueue.poll().invoke()
}
}
虽然这种方法无法避免配置更改,但一旦活动轮换,我们就会失去延迟调用。
dialog.show() 执行的函数不是匿名类 - 您最终可能会引入内存泄漏。测试:
我测试优雅显示对话框的方法是Espresso 仪器测试。
我还将对存储/执行延迟执行的视图模型进行单元测试。 如果我们考虑使用 MVP 或MVVM architectural pattern 构建代码,我们可以将延迟执行队列存储在架构类成员之一中,并对它们进行单元测试。
我还会将LeakCanary 作为防止内存泄漏的安全网。
可选地,我们仍然可以使用robolectric 并开发集成测试验证:
onSaveInstanceState 被调用后推迟 dialog.show() 执行onSaveInstanceState 并再次返回resumed 状态后存储的内部队列正在执行待处理的dialog.show() 执行。created/started/resumed 状态,则立即执行dialog.show()。这就是我目前所拥有的一切,希望您能找到令人满意的测试套件,根据建议的方法验证正确的对话框显示。
【讨论】: