Room MigrationTestHelper のコンストラクタ deprecated 対応メモ


Room のマイグレーションのテストに関しての公式のガイドがあるのですが、このサンプルコードで使われている `MigrationTestHelper` のコンストラクタは deprecated になっていて、素直に書くと取り消し線が引かれている状態になっています:

https://developer.android.com/training/data-storage/room/migrating-db-versions#all-migrations-test

ガイドはそのうち更新されるでしょうが、この機会に deprecated でないやりかたではどう書くのが良いか調べました:

![depreacted.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/c64d4bd8-25e2-860f-81dc-05b05dc66722.png)

## deprecated のコンストラクタ

サンプルで使われている deprecated になっているコンストラクタはこれです:

https://developer.android.com/reference/androidx/room/testing/MigrationTestHelper#MigrationTestHelper(android.app.Instrumentation,%20java.lang.String,%20androidx.sqlite.db.SupportSQLiteOpenHelper.Factory)

引数に `Instrumentation`, `String`, `SupportSQLiteOpenHelper.Factory` をとるコンストラクタです。

![MigrationTestHelper_ _ _Android_Developers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/ba967360-e5b0-6175-707c-3992973715d5.png)

ページの注意書きにあるように、このコンストラクタではバージョン `TODO` で導入された `AutoMigration` の指定ができない (`AutoMigrationSpec` による指定ができない) ので、新しいコンストラクタを使うことがオススメされているということですね。

## オススメされたコンストラクタ

一方、これの代替となるコンストラクタは 3 つあります:

![MigrationTestHelper_ _ _Android_Developers-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/957f1b9c-9ed5-35e7-a9a2-2e313344406b.png)
![MigrationTestHelper_ _ _Android_Developers-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/ff82a910-16f8-a8be-4671-812ca748b304.png)
![MigrationTestHelper_ _ _Android_Developers-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/876db53f-c12f-9a46-7449-c75f541f952f.png)

2 番目のコンストラクタが `AutoMigration` に関する指定ができることがポイントで、一番使いそうなものではないでしょうか。使っていない場合は未指定にして 1 番目のコンストラクタを使うか、または 空のリストを渡すようにすればよいでしょう。


## サンプルをオススメに書き換える

これをふまえてサンプルにある [Test a single migration](https://developer.android.com/training/data-storage/room/migrating-db-versions#single-migration-test), [Test all migrations](https://developer.android.com/training/data-storage/room/migrating-db-versions#all-migrations-test) の例を書き換えると

```diff_kotlin
     @get:Rule
     val helper: MigrationTestHelper = MigrationTestHelper(
         InstrumentationRegistry.getInstrumentation(),
-        AppDatabase::class.java.canonicalName,
-        FrameworkSQLiteOpenHelperFactory()
+        AppDatabase::class.java,
     )
```

単に [3 番目の引数をなくしたコンストラクタ](https://developer.android.com/reference/androidx/room/testing/MigrationTestHelper#MigrationTestHelper(android.app.Instrumentation,%20java.lang.Class%3C?%20extends%20androidx.room.RoomDatabase%3E)) である 1 番目を使うのが良いということになるでしょう。

## `AutoMigration` を指定する場合

さらに `AutoMigrationSpec` を指定した `AutoMigration` がある場合は

```diff_kotlin
    @get:Rule
    val helper: MigrationTestHelper = MigrationTestHelper(
        InstrumentationRegistry.getInstrumentation(),
        AppDatabase::class.java,
        listOf(AppDatabase.AutoMigrationSpec1()),
    )
```

必要な `AutoMigrationSpec` のリストを 3 番目の引数に追加することで考慮できます。

あとはマイグレーションを行われた後の状態をテストするみたいなコードを書いてできあがりとなります:

```kotlin
@RunWith(AndroidJUnit4::class)
class MigrationTest {
    private val TEST_DB = "migration-test"

    // 1. 手動でのマイグレーションを列挙する
    private val ALL_MIGRATIONS = arrayOf(MIGRATION_1_2)


    @get:Rule
    val helper: MigrationTestHelper = MigrationTestHelper(
        InstrumentationRegistry.getInstrumentation(),
        AppDatabase::class.java,
        // 2. ここに必要な AutoMigratinSpec を列挙する (あれば)
        listOf(
            AppDatabase.AutoMigrationSpec1(),
        ),
    )

    @Test
    @Throws(IOException::class)
    fun migrateAll() {
        helper.createDatabase(TEST_DB, 1).apply {
            close()
        }

        Room.databaseBuilder(
            InstrumentationRegistry.getInstrumentation().targetContext,
            AppDatabase::class.java,
            TEST_DB
        ).addMigrations(*ALL_MIGRATIONS).build().apply {
            // 3. ここでマイグレーション後の状態の検証を行ったりできる
            // ...
            openHelper.writableDatabase.close()
        }
    }

}
```

なんてことはないですが、備忘録として。
誰かのお役に立てば幸いです。