📜  使用JUnit在Android中测试会议室数据库

📅  最后修改于: 2021-05-10 15:40:05             🧑  作者: Mango

在本文中,我们将在android中测试Room数据库。在这里,我们使用JUnit来测试我们的代码。 JUnit是Java应用程序的“单元测试”框架,默认情况下已包含在android studio中。它是单元和UI测试的自动化框架。它包含注释,比如@测试,@Before,@After等等,下面我们将只使用@Test注解让文章很容易理解。请注意,我们将使用Kotlin语言实施此项目。

分步实施

步骤1:创建一个新项目

要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。请注意,选择Kotlin作为编程语言。

步骤2:添加依赖项

build.gradle(项目)内部,在依赖项下添加以下代码。它包含Room Db,Coroutiene,JUnit,Truth等的依赖项。

在编写测试之前,首先要创建房间数据库

第3步:创建一个新的模型类“ Language.kt”

创建一个新的类“ Language.kt ”,并用@Entity对其进行注释并传递表名。

Kotlin
import androidx.room.Entity
import androidx.room.PrimaryKey
  
@Entity(tableName = "language")
data class Language(
    val languageName : String="",
    val experience : String=""
) {
    @PrimaryKey(autoGenerate = true)
    var id : Long=0
}


Kotlin
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
  
@Dao
interface LanguageDao {
    // Write two functions one for adding language to the database 
    // and another for retrieving all the items present in room db.
    @Insert
    suspend fun addLanguage(language: Language)
  
    @Query("SELECT * FROM language ORDER BY languageName DESC")
    suspend fun getAllLanguages(): List
}


Kotlin
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
  
@Database(entities = [Language::class] , version = 1)
abstract class LanguageDatabase : RoomDatabase() {
  
    // get reference of the dao interface that we just created
    abstract fun getLanguageDao() : LanguageDao
  
    companion object{
        private const val DB_NAME = "Language-Database.db"
          
        // Get reference of the LanguageDatabase and assign it null value
        @Volatile
        private var instance : LanguageDatabase? = null
        private val LOCK = Any()
  
        // create an operator fun which has context as a parameter
        // assign value to the instance variable
        operator fun invoke(context: Context) = instance ?: synchronized(LOCK){
            instance ?: buildDatabase(context).also{
                instance = it
            }
        }
        // create a buildDatabase function assign the required values
        private fun buildDatabase(context: Context) = Room.databaseBuilder(
            context.applicationContext,
            LanguageDatabase::class.java,
            DB_NAME
        ).fallbackToDestructiveMigration().build()
    }
}


Kotlin
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import junit.framework.TestCase
import kotlinx.coroutines.runBlocking
import org.junit.*
import org.junit.runner.RunWith
  
@RunWith(AndroidJUnit4::class) // Annotate with @RunWith
class LanguageDatabaseTest : TestCase() {
    // get reference to the LanguageDatabase and LanguageDao class
    private lateinit var db: LanguageDatabase
    private lateinit var dao: LanguageDao
  
    // Override function setUp() and annotate it with @Before
    // this function will be called at first when this test class is called
    @Before
    public override fun setUp() {
        // get context -- since this is an instrumental test it requires
        // context from the running application
        val context = ApplicationProvider.getApplicationContext()
        // initialize the db and dao variable 
        db = Room.inMemoryDatabaseBuilder(context, LanguageDatabase::class.java).build()
        dao = db.getLanguageDao()
    }
  
    // Override function closeDb() and annotate it with @After
    // this function will be called at last when this test class is called
    @After
    fun closeDb() {
        db.close()
    }
  
    // create a test function and annotate it with @Test 
    // here we are first adding an item to the db and then checking if that item 
    // is present in the db -- if the item is present then our test cases pass
    @Test
    fun writeAndReadLanguage() = runBlocking {
        val language = Language("Java", "2 Years")
        dao.addLanguage(language)
        val languages = dao.getAllLanguages()
        assertThat(languages.contains(language)).isTrue()
    }
}


步骤4:创建Dao接口

创建一个新的类“ LanguageDao.kt ”,并使用@Dao对其进行注释。添加了注释以更好地理解代码。

科特林

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
  
@Dao
interface LanguageDao {
    // Write two functions one for adding language to the database 
    // and another for retrieving all the items present in room db.
    @Insert
    suspend fun addLanguage(language: Language)
  
    @Query("SELECT * FROM language ORDER BY languageName DESC")
    suspend fun getAllLanguages(): List
}

步骤5:创建一个数据库类

创建一个新的抽象类“ LanguageDatabase.kt ”,并使用@Database对其进行注释。下面是添加的LanguageDatabase.kt类注释的代码,以使您更好地理解。

科特林

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
  
@Database(entities = [Language::class] , version = 1)
abstract class LanguageDatabase : RoomDatabase() {
  
    // get reference of the dao interface that we just created
    abstract fun getLanguageDao() : LanguageDao
  
    companion object{
        private const val DB_NAME = "Language-Database.db"
          
        // Get reference of the LanguageDatabase and assign it null value
        @Volatile
        private var instance : LanguageDatabase? = null
        private val LOCK = Any()
  
        // create an operator fun which has context as a parameter
        // assign value to the instance variable
        operator fun invoke(context: Context) = instance ?: synchronized(LOCK){
            instance ?: buildDatabase(context).also{
                instance = it
            }
        }
        // create a buildDatabase function assign the required values
        private fun buildDatabase(context: Context) = Room.databaseBuilder(
            context.applicationContext,
            LanguageDatabase::class.java,
            DB_NAME
        ).fallbackToDestructiveMigration().build()
    }
}

步骤6:创建一个测试类

为了创建LanguageDatabase.kt的测试类,请在LanguageDatabase上单击鼠标右键,然后单击“生成”,然后选择测试。将打开一个对话框,从对话框中选择“测试库”作为JUnit4 ,并将类名保留为默认名称,即LanguageDatabaseTest ,然后单击“确定” 。之后,将打开另一个对话框以选择目标目录,然后选择具有..app \ src \ AndoidTest \的目录。因为我们的测试类需要应用程序中的上下文。以下是指导您创建测试类的屏幕截图。

步骤7:使用LanguageDatabaseTest.kt类

转到LanguageDatabaseTest.kt文件并编写以下代码。在代码内部添加了注释,以更详细地了解代码。

科特林

import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import junit.framework.TestCase
import kotlinx.coroutines.runBlocking
import org.junit.*
import org.junit.runner.RunWith
  
@RunWith(AndroidJUnit4::class) // Annotate with @RunWith
class LanguageDatabaseTest : TestCase() {
    // get reference to the LanguageDatabase and LanguageDao class
    private lateinit var db: LanguageDatabase
    private lateinit var dao: LanguageDao
  
    // Override function setUp() and annotate it with @Before
    // this function will be called at first when this test class is called
    @Before
    public override fun setUp() {
        // get context -- since this is an instrumental test it requires
        // context from the running application
        val context = ApplicationProvider.getApplicationContext()
        // initialize the db and dao variable 
        db = Room.inMemoryDatabaseBuilder(context, LanguageDatabase::class.java).build()
        dao = db.getLanguageDao()
    }
  
    // Override function closeDb() and annotate it with @After
    // this function will be called at last when this test class is called
    @After
    fun closeDb() {
        db.close()
    }
  
    // create a test function and annotate it with @Test 
    // here we are first adding an item to the db and then checking if that item 
    // is present in the db -- if the item is present then our test cases pass
    @Test
    fun writeAndReadLanguage() = runBlocking {
        val language = Language("Java", "2 Years")
        dao.addLanguage(language)
        val languages = dao.getAllLanguages()
        assertThat(languages.contains(language)).isTrue()
    }
}

步骤8:运行测试

要运行测试用例,请单击类名附近的小运行图标,然后选择运行LanguageDatabaseTest。如果所有测试用例都通过,您将在“运行”控制台中看到一个绿色的勾号。在我们的案例中,所有测试均已通过。

Github Repo在这里

想要一个节奏更快,更具竞争性的环境来学习Android的基础知识吗?
单击此处前往由我们的专家精心策划的指南,以使您立即做好行业准备!