模拟室数据库,用于单元测试

时间:2019-01-22 15:40:46

标签: android unit-testing android-room

我正在尝试对我的业务逻辑进行一些单元测试。

数据是读写到Room数据库中的,因此逻辑取决于我数据库中的内容。

我可以轻松buildInMemoryDatabase并测试所有逻辑,但是可以使用缓慢且需要连接设备的仪器测试

我只想在将RoomRepository替换为Repository接口的其他实现的情况下运行单元测试

class RoomRepository(
    private val database: RoomDatabase //actual room database
): Repository {

    override fun getFooByType(type: Int): Maybe<List<Item>> {
        return database.fooDao()
            .getFooByType(type)
            .map { names ->
                names.map { name -> Item(name) }
            }
            .subscribeOn(Schedulers.io())
    }
}

也许可以在主机上运行Room sqlite吗?

也许还有其他解决方案?

3 个答案:

答案 0 :(得分:2)

在RoomDatabase周围创建一个名为“ Repository”的包装器类,并具有公开Dao对象的方法。这样,我们可以像下面这样轻松地模拟存储库类

Open class Repository(private val roomDatabase:RoomDatabase){

  open fun productsDao():ProductsDao = roomDatabase.productDao()
  open fun clientsDao():ClientsDao = roomDatabase.clientsDao()

  //additional repository logic here if you want

}

现在,在测试中,可以像这样轻松模拟此类

val repositoryMock = mock(Repository::class.java)
val productsDaoMock = mock(ProductsDao::class.java)

when(repositoryMock.productsDao()).thenReturn(productsDaoMock)
when(productsDaoMock.getProducts()).thenReturn(listof("ball","pen")

因此,在项目的所有位置注入并使用存储库类而不是RoomDatabase类,以便可以轻松模拟存储库和所有Dao

答案 1 :(得分:0)

通常您可以通过@Dao界面访问数据库。这些很容易被嘲笑。

dao是从您实际的RoomDatabase的抽象方法返回的,因此也可以轻松地对其进行模拟。

只需使用模拟实例化您的RoomRepository并正确设置它们即可。

答案 2 :(得分:0)

请参阅本文。 https://developer.android.com/training/data-storage/room/testing-db

这是单元测试,并且不像您想的那样像UI测试一样缓慢。

  

推荐的测试数据库实现的方法是编写在Android设备上运行的JUnit测试。由于这些测试不需要创建活动,因此它们的执行速度应该比UI测试快。