【问题标题】:Roboelectric with Room Database for androidRobolectric 与安卓房间数据库
【发布时间】:2019-01-23 12:33:12
【问题描述】:

如何借助 Roboeletric 对 Room Database 进行单元测试?

我不想进行仪器测试。

【问题讨论】:

    标签: android-room robolectric


    【解决方案1】:

    据我所知可以这样做

    //@RunWith(AndroidJUnit4::class)
    @RunWith(RobolectricTestRunner::class)
    class WordDaoTest {
        private lateinit var wordRoomDatabase: WordRoomDatabase
        private lateinit var wordDao: WordDao
    
        @get:Rule
        var instantTaskExecutor = InstantTaskExecutorRule()
    
        @Before
        fun createDb() {
            val context = InstrumentationRegistry.getInstrumentation().targetContext
            wordRoomDatabase = Room.inMemoryDatabaseBuilder(context, WordRoomDatabase::class.java).allowMainThreadQueries().build()
            wordDao = wordRoomDatabase.wordDao()
    
            wordRoomDatabase.wordDao().insertAll(listOf<Word(Word("one"),Word("two"),Word("three"))
        }
    
        @After
        fun closeDb() {
            wordRoomDatabase.close()
        }
    
        @Test
        fun testGetName() {
            Assert.assertThat(getValue(wordDao.getAllLiveWords()).size, equalTo(3))
        }
    }
    

    似乎您在构建数据库时需要 allowMainThreadQueries()。

    我不确定为什么每个人都在仪器测试中测试 Dao,而它可以在单元测试中完成,然后被添加到代码覆盖中(也许其他人有一些见解)

    这段代码在 Kotlin 中,但我确信它会以同样的方式转换为 java。

    这是提供给我的,但是为什么它不被认为是最佳实践 https://developer.android.com/training/data-storage/room/testing-db

    注意:尽管此设置允许您的测试非常快速地运行,但不建议这样做,因为您设备上运行的 SQLite 版本(以及您的用户设备)可能与您主机上的版本不匹配。

    【讨论】:

    • “可能与主机上的版本不匹配”这是我能想到的不加快测试速度的最奇怪的原因。有无数的安卓设备,运行着不同版本的操作系统。是什么让任何人认为在单个设备/模拟器上缓慢而缓慢地测试代码比在主机上运行它们更好?
    • 我无法在测试实现中获取 InstrumentationRegistry.getInstrumentation().targetContext 我的意思不是仪器。有什么原因吗?
    【解决方案2】:

    Robolectric 可以通过 Room 支持此类 JVM 单元测试。

    要获得所需的上下文,请在 build.gradle 中添加以下依赖项:

    testImplementation 'androidx.test:core:1.2.0'
    

    假设我们有一个包装 Room Dao 的存储库类。这是一个简单的例子:

    @RunWith(RobolectricTestRunner::class)
    @Config(sdk = [28]) // This config setting is the key to make things work
    class FooRepositoryTest {
    
        @get:Rule
        var instantTask = InstantTaskExecutorRule()
    
        private lateinit var database: MyDatabase
    
        private lateinit var sut: FooRepository
    
        @Before
        fun setUp() {
            val context = ApplicationProvider.getApplicationContext<Context>()
            database = Room.inMemoryDatabaseBuilder(context, MyDatabase::class.java)
                .allowMainThreadQueries()
                .build()
            sut = FooRepository(database.fooDao())
        }
    
        @After
        fun tearDown() {
            database.close()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-01-21
      • 2018-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多