如何借助Roboeletric进行Room数据库的单元测试?
我不想进行仪器测试。
我不想进行仪器测试。
根据我的了解,可以像这样完成
//@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()
}
}