Open1

DAOテスト

るるすたるるすた

依存関係追加

いつものようにlibs.versions.tomlにバージョンとライブラリを追加。

build.gradle.kts(Module:app)に依存関係を追加

一部エラーが出るけど、気にしない。
ライブラリを作ったらエラーが解消されるので。

dependencies{
    //room用
    androidTestImplementation(libs.androidx.room.testing)
    androidTestImplementation(libs.androidx.runner)

[versions]

2025年5月23日時点の最新。

roomTesting = "2.7.1"
runner = "1.6.2"

[libraries]

androidx-room-testing = { module = "androidx.room:room-testing", version.ref = "roomTesting" }
androidx-runner = { module = "androidx.test:runner", version.ref = "runner" }

SyncNow!!!!

build.gradle.kts(Module:app)に依存関係を追加

dependencies{
    //room用
    androidTestImplementation(libs.androidx.room.testing)
    androidTestImplementation(libs.androidx.runner)

テスト用ファイル作成

DAOの名前がDrillDaoなので、ファイル名はDrillDaoTestにした。
Androidテストの中にファイルを作成。

テスト用DB作成

アノテーションをつける

Roomを使ったテストをするので、RunWithアノテーションをつける
また、コルーチンAPIを使うので、OptInのアノテーションもつける

@OptIn(ExperimentalCoroutinesApi::class)    //これ!
@RunWith(AndroidJUnit4::class)  //これ!
class DrillDaoTest {
}

変数の用意

データベース用とDAO用の2つ準備

@RunWith(AndroidJUnit4::class)
class DrillDaoTest {
   private lateinit var database: AppDatabase
   private lateinit var dao: DrillDao

Beforeで最初にデータベースを作成

メモリ上で動く仮想DBを作る。メインスレッドで動くようにしておく。

    @Before
    fun setup() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        //test用のDBを作成(メモリ上で動く)
        database = Room.inMemoryDatabaseBuilder(
            context,
            AppDatabase::class.java  //databaseでない点注意
        )
            .allowMainThreadQueries()   //メインスレッドでも動くようにする
            .build()                    //DB作成
        //Dao取得
        dao = database.drillDao()
    }

Afterで最後にデータベースを閉じる

データベースが閉じるときにエラーが発生することを考慮して、
Throwsアノテーションを関数の前につけておく。

    @After
    @Throws(IOException::class)
    fun closeDB() {
        database.close()
    }

test用のデータをデータベースに登録

データベースが空だとテストできないのでデータ登録用の関数を作成。
IDは自動付与形式としているので、登録しない。
→登録するとテスト時にエラーになる。

    /******テスト用の登録メソッド******/
    val data = listOf(
        DrillEntity(operator = "たし算",level = 1, score = 500,playedAt = 20250521L),
        DrillEntity(operator = "たし算",level = 3, score = 2500,playedAt = 20250522L),
        DrillEntity(operator = "ひき算",level = 5, score = 10000,playedAt = 20250523L),
    )

    private suspend fun insertDrillResult() {
        data.forEach { 
            dao.insert(it)
        }
    }

準備ができたのでテストを書いていく

テストの書き方はユニットテストとかと一緒。
@Testから始める
ただし、DAOは非同期処理しているので関数名の後ろにrunTestをつけないと
エラーになる。

    @Test
    fun daoInsert_ドリルの結果がDBに登録されること() = runTest {
        insertDrillResult()  //DBにデータを登録
        val result = dao.getAll().first()  //登録したデータを変数に入れる
        val sortedResult= data.sortedByDescending { it.playedAt }   //テストで突っ込んだデータ
        val expected = result.sortedByDescending { it.playedAt }  //DBに存在しているデータ
        //ID以外を検証
        for (i in expected.indices){
            assertEquals(expected[i].operator,sortedResult[i].operator)
            assertEquals(expected[i].level,sortedResult[i].level)
            assertEquals(expected[i].score,sortedResult[i].score)
            assertEquals(expected[i].playedAt,sortedResult[i].playedAt)
        }
    }

テストは無事合格しました!
引き続き色んなテストをしていこう~