【问题标题】:Is there a way to properly Mock a room database?有没有办法正确模拟房间数据库?
【发布时间】:2019-04-08 19:12:36
【问题描述】:

我正在尝试使用 Mockito 模拟我的房间数据库,以便我可以在我的存储库中测试复杂的算法。无论我踏入哪个方向,都会遇到大量不同的错误。

首先我尝试模拟整个数据库对象,这创建了一个空接口异常。

为了解决这个问题,我使用了 Room 的静态对象生成器。 (这是一个检测单元测试,所以我可以访问底层的 Android 依赖项)

import org.mockito.*
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyDouble

class BasicReposTest {


@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java)

@get:Rule
val mockitoRule: MockitoRule = MockitoJUnit.rule()

@Mock
lateinit var mockedDb : AppDatabase

@Before
fun setTheDatabase() {
    val context = ApplicationProvider.getApplicationContext<Context>()

    mockedDb = Room.inMemoryDatabaseBuilder(
        context, AppDatabase::class.java).build()

}

@Test
fun doesReposRequestBounds() {

    `when`(mockedDb.momentDao().findMomentsByBound(ArgumentMatchers.anyDouble(), ArgumentMatchers.anyDouble(),
        anyDouble(), ArgumentMatchers.anyDouble())).thenReturn(momentList)

    //Request first set of moments
    repos.queryMapMoments(bounds, 20.toFloat())
    //Do we get a list of moments sent to livedata?
    assertTrue(mappedMoments.value!!.size >= momentList.size)

    val list : List<Moment> = mappedMoments.value!!

    for (value in list) {
        System.out.println("D " + "RequestMomentsFromDatabaseByBoundsTest    " + "MID = " + value.mId )
    }
}

有了这个,我收到了一个误用的匹配器异常...... ++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 此处检测到错误放置或误用的参数匹配器:

-> 在 com.example.barrechat108.RepositoryTests.doesReposRequestBounds(RepositoryTests.kt:138) -> 在 com.example.barrechat108.RepositoryTests.doesReposRequestBounds(RepositoryTests.kt:138) -> 在 com.example.barrechat108.RepositoryTests.doesReposRequestBounds(RepositoryTests.kt:139) -> 在 com.example.barrechat108.RepositoryTests.doesReposRequestBounds(RepositoryTests.kt:139)`

您不能在验证或存根之外使用参数匹配器。 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++

【问题讨论】:

  • 所以,它实际上并不是在模拟 DAO,这是有道理的,因为 DAO 是一个复杂的注释接口。但我不知道如何正确模拟数据库对象:/

标签: android unit-testing kotlin mockito android-room


【解决方案1】:

在测试时,您可以将房间数据库构建为内存数据库。因此,存储的所有内容只会持续到进程关闭。所以什么都不会持久,非常适合测试!

代码: Room.inMemoryDatabaseBuilder(context, TestDatabase::class.java).build()

【讨论】:

    【解决方案2】:

    我对这个解决方案并不完全感到自豪,但它确实有效。我没有将完整的数据库对象传递给我的 Repository 类的构造函数,而是创建了另一个直接采用 dao 的重写构造函数。这样我就可以简单地模拟 dao,而不必制作一些根本无法工作的奇怪的数据库函数链。

    【讨论】:

      猜你喜欢
      • 2022-10-18
      • 2019-12-03
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多