Unit Testing Pada Room Database
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 PostEntity
dan 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
, delete
dan 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 PostDaoTest
di androidTest
directory. kenapa kita buat di androidTest
bukan di test
directory 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.