【问题标题】:Mock Room database for Unit tests用于单元测试的 Mock Room 数据库
【发布时间】:2019-01-22 15:40:46
【问题描述】:

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

数据被读取并写入 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?

也许还有其他解决方案?

【问题讨论】:

  • 你能在你的测试用例中访问数据库吗?当我创建 Dao 类的对象时,我收到 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.io.File.getPath()' on a null object reference 错误。可能是什么问题?

标签: android unit-testing android-room


【解决方案1】:

围绕 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

【讨论】:

    【解决方案2】:

    您通常通过@Dao 接口访问数据库。这些可以很容易地模拟。

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

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

    【讨论】:

    • 也许您可以添加一个链接或一些示例如何制作?我只是不明白我的数据将存储在哪里
    • 这是单元测试。数据永远不会被存储。 mock 提供测试数据,您可以验证函数调用。您不必关心数据库的实际工作方式。为此,您可以在 Kotlin 上使用 MockitoMockk
    • 这回答了如何测试使用 dao 对象的类,但它不会帮助你测试你的 sql
    【解决方案3】:

    请参考这篇文章。 https://developer.android.com/training/data-storage/room/testing-db

    它是单元测试,而不是像你想象的那样缓慢的 UI 测试。

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

    【讨论】:

    • 您没有回答他的问题,他是在询问如何模拟房间数据库以进行单元测试,而不是尝试测试数据库本身。这就是您发布的文章所指的内容。
    猜你喜欢
    • 1970-01-01
    • 2018-10-17
    • 2023-01-23
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多