用于单元测试的 Mock Room 数据库

nut*_*ter 8 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())
    }
}
Run Code Online (Sandbox Code Playgroud)

也许有一种方法可以在主机上运行 Room sqlite?

也许还有另一种解决方案?

Sun*_*vel 5

在 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

}
Run Code Online (Sandbox Code Playgroud)

现在,在测试中,这个类可以很容易地被模拟

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

when(repositoryMock.productsDao()).thenReturn(productsDaoMock)
when(productsDaoMock.getProducts()).thenReturn(listof("ball","pen")
Run Code Online (Sandbox Code Playgroud)

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


tyn*_*ynn 1

您通常通过接口访问数据库@Dao。这些很容易被嘲笑。

daos 是从您的实际的抽象方法返回的RoomDatabase,因此这也可以很容易地被模拟。

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