由于其技术的独特性及其简化Android应用程序开发的方式,因此对LiveData
进行测试是一个有趣的挑战。
最近,我开始开发一个Android应用程序,以继续学习Kotlin的动力。 我最近的经验是在Architecture Components上 ,这篇简短的博客文章特别关注使用LiveData
时对DAO进行单元测试。
什么是LiveData?
LiveData
是可感知生命周期的可观察数据持有者,可帮助您对数据源中的更改做出反应。 就我而言,我将其与Room
结合使用以确保我的应用对数据库中可用的新数据做出反应。
我们简单的DAO
对于此博客文章,我们仅假设我们有一个非常简单的DAO,其外观如下:
这只是一个DAO,可以帮助您获取帖子。
如您所见,该函数的返回类型不仅是普通的List<Post>
而且LiveData
其包装在LiveData
实例中。 这很棒,因为我们可以一次获取帖子列表的一个实例,然后观察更改并对其做出反应 。
让我们测试一下
Android Developer文档中有一个关于如何对DAO进行单元测试的简洁示例:
这个非常简单的测试旨在测试数据是否正确公开,并且一旦将帖子添加到数据库中,就可以通过getAll()
调用反映出来。
不幸的是,到我们对此断言时, LiveData
实例的值将不会被填充,并使我们的测试失败。 这是因为LiveData
使用面向生命周期的异步机制来填充基础数据,并希望注册观察者以告知数据更改。
观察数据
LiveData
提供了一种方便的观察方法,该方法允许在数据更改时观察数据。 我们可以使用它来注册一个观察者,该观察者将对期望值进行断言。
观察方法具有以下签名:
void observe( LifecycleOwner owner, Observer <T> observer)
它期望观察者实例和所有者拥有生命周期。 在我们的案例中,我们只希望将观察者保持在适当的位置以能够对更改的数据进行断言。 我们不希望每次数据更改时都评估相同的断言。
拥有自己的生命周期
然后,我们可以做的是建立一个拥有自己生命周期的观察者实例。 处理onChange事件后,我们将标记观察者生命周期为已破坏,让框架完成其余工作。
让我们看看观察者代码是什么样的:
该观察器实现接受一个lambda ,它将作为onChange事件的一部分执行。 处理程序完成后,其自身的生命周期将继续将其自身标记为ON_DESTROY
,这将触发从LiveData
实例的删除过程。
然后,我们可以在LiveData上创建扩展,以利用这种观察者:
fun <T> LiveData<T>.observeOnce(onChangeHandler: (T) -> Unit) {
val observer = OneTimeObserver(handler = onChangeHandler)
observe(observer, observer)
}
让我们再次测试
这次需要注意几件事。
首先,我们利用InstantTaskExecutorRule
优势。 这是一个有用的实用程序规则,它负责将后台异步任务执行程序与同步执行程序交换。 这对于能够确定性地测试我们的代码至关重要。 (如果您想进一步了解JUnit规则,请查看此内容)。
除此之外,我们现在利用编写的LiveData
扩展来编写断言:
postDao.getAll().observeOnce {
assertEquals(0, it.size)
}
我们刚刚通过将所有细节留在我们的观察者实现中以更加紧凑和更具表现力的方式断言。 现在,我们以确定性的方式对LiveData
实例进行声明,从而使此类测试更易于读写。
结论
希望本文有助于您更有效地为DAO编写测试。 这是我最早使用Kotlin和Android的经历之一:请随时发表评论,提出更好的解决方案。
Irvan Smith 在 Unsplash 上的 封面照片
From: https://hackernoon.com/testing-livedata-on-android-d717c241efb1