How to do unit testing of Room Database with the help of Roboeletric?
I don't want to do instrumentation testing.
From what I can tell it can be done like this
//@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))
}
}
It seems though you need allowMainThreadQueries() in the build of the DB.
I am not sure as to why everyone tests the Dao in the instrumentation test when it can be done in the Unit Test and then be added to code coverage (maybe someone else has some insight)
This code is in Kotlin but I am sure it would translate to java just the same.
This was provided to me however as to why it's not considered to be best practice https://developer.android.com/training/data-storage/room/testing-db
Note: Even though this setup allows your tests to run very quickly, it isn't recommended because the version of SQLite running on your device—and your users' devices—might not match the version on your host machine.
Robolectric can support such JVM unit tests with Room.
To get the required context, please add below dependency in your build.gradle:
testImplementation 'androidx.test:core:1.2.0'
Let's assume that we have a repository class which wraps the Room Dao. And here's a quick example:
@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()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With