【发布时间】:2019-01-23 12:33:12
【问题描述】:
如何借助 Roboeletric 对 Room Database 进行单元测试?
我不想进行仪器测试。
【问题讨论】:
如何借助 Roboeletric 对 Room Database 进行单元测试?
我不想进行仪器测试。
【问题讨论】:
据我所知可以这样做
//@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 版本(以及您的用户设备)可能与您主机上的版本不匹配。
【讨论】:
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()
}
}
【讨论】: