Unit Testing Pada Room Database

Yusuf Safrudin
TLabCircle
Published in
3 min readJun 25, 2022

Di dalam tulisan ini kita akan mencoba untuk membuat unit testing terhadap room database, jika kalian belum familiar dengan Room, silahkan lihat dokumentasi terkait Room Database disini.

Ada beberapa dependency yang perlu ditambahkan di build.gradle:

plugins {
id 'kotlin-kapt'
}
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"

implementation 'androidx.test.ext:junit-ktx:1.1.3'
testImplementation 'junit:junit:4.13.2'
testImplementation 'com.google.truth:truth:1.1.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'com.google.truth:truth:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.2.1"

Entity

Kita akan membuat satu class bernama PostEntitydan perlu kita beri anotasi@Entity yang mana menunjukkan bahwa class Post merepresentasikan tabel Post.

@Entity(tableName = "post")
data class PostEntity(
@PrimaryKey
@ColumnInfo
var id: Int,

@ColumnInfo
var userId: Int,

@ColumnInfo
val tittle: String,

@ColumnInfo
val body: String
)

Data access object (DAO)

Untuk mengakses data pada tabel yang kita buat, kita perlu membuat dao untuk berinteraksi dengan tabel seperti melakukan insert, update, deletedan getData. Karena untuk melakukan operasi pada database perlu berjalan di background maka disini kita akan menggunakan coroutines.

@Dao
interface PostDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertPost(entity: PostEntity)

@Update
suspend fun updatePost(entity: PostEntity)

@Delete
suspend fun deletePost(entity: PostEntity)

@Query("Select * from post")
suspend fun getAllPost():List<PostEntity>
}

Database Class

Selanjutnya kita buat database nya

@Database(
entities = [
PostEntity::class
],
exportSchema = false,
version = 1
)
abstract class AppDatabase : RoomDatabase() {
abstract fun postDao(): PostDao

companion object {
@Volatile
private var database: AppDatabase? = null

fun getInstance(context: Context): AppDatabase =
database ?: synchronized(this) {
database
?: buildDatabase(context).also { database = it }
}

private fun buildDatabase(context: Context) =
Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"app_database"
).build()

}
}

Unit Test

Setelah semua setup database yang diperlukan selesai, selanjutnya kita akan membuat unit testnya. Buat test class PostDaoTestdi androidTestdirectory. kenapa kita buat di androidTest bukan di testdirectory karena RoomDatabase membutuhkan context . untuk melakukan database test ini kita perlu tersambung dengan device atau emulator. disini menggunakan memory untuk membuat temporary database sehingga tidak mempengaruhi database utama karena akan terhapus ketika semua test case selesai dijalankan.

@ExperimentalCoroutinesApi
@RunWith(AndroidJUnit4::class)
class PostDaoTest {
private lateinit var database: AppDatabase
private lateinit var dao: PostDao

@Before
fun setup() {
val context = ApplicationProvider.getApplicationContext<Context>()
database = Room.inMemoryDatabaseBuilder(context,
AppDatabase::class.java
).allowMainThreadQueries().build()
dao = database.postDao()
}

@After
fun closeDb() {
database.close()
}

@Test
fun writeAndReadPost() = runBlocking {
val entity = PostEntity(
1,
1,
"my testing tittle",
"my testing body"
)
dao.insertPost(entity)
val listPost = dao.getAllPost()
assertThat(listPost).contains(entity)
}

@Test
fun updateAndReadPost() = runBlocking {
val entity = PostEntity(
1,
1,
"my testing tittle",
"my testing body"
)
dao.insertPost(entity)

val updateEntity = PostEntity(
1,
1,
"update testing tittle",
"update testing body"
)
dao.updatePost(updateEntity)
val listPost = dao.getAllPost()
assertThat(listPost).contains(updateEntity)
}

@Test
fun deletePost() = runBlocking {
val entity = PostEntity(
1,
1,
"my testing tittle",
"my testing body"
)
dao.insertPost(entity)
dao.deletePost(entity)
val listPost = dao.getAllPost()
assertThat(listPost).isEmpty() // import com.google.common.truth.Truth.assertThat
}

}

@Test: annotation bahwa method tersebut adalah test case.
@Before: annotation yang digunakan sebagai tanda bahwa method dijalankan sebelum setiap test case dieksekusi.
@After: annotation yang digunakan sebagai tanda bahwa method dijalankan setelah setiap test case dieksekusi.
assertThat: digunakan untuk membandingkan value sebenarnya dengan value yang diharapkan apakah bernilai true atau false.

Run PostDaoTest:

Silahkan tunggu proses build nya….maka akan tampil hasil dari test yang dibuat seperti dibawah ini.

--

--