android room migrations
要开启
exportSchema = true
迁移测试
导入:room-testing
错误
androidx.test.ext 报错 Failed to resolve: androidx.test.ext:junit:1.3.0
去掉:androidx.test.ext 的版本号,version.ref = "junitVersion" ,由composeBom 决定版本
测试代码
import android.content.Context import androidx.room.Room import androidx.room.testing.MigrationTestHelper import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistryimport com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import java.io.IOException @RunWith(AndroidJUnit4::class) class MigrationTest { private val TEST_DB = "migration-test" @get:Rule val helper: MigrationTestHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), // MigrationDb::class.java.canonicalName, TestDatabase::class.java, listOf(), FrameworkSQLiteOpenHelperFactory() ) @Test @Throws(IOException::class) fun migrate1To2() { var db = helper.createDatabase(TEST_DB, 2).apply { // Database has schema version 1. Insert some data using SQL queries. // You can't use DAO classes because they expect the latest schema. execSQL("INSERT INTO user (first_name,last_name) VALUES('[email protected]', 'Philipp')"); execSQL("INSERT INTO user (first_name,last_name) VALUES('first_name', 'test')"); val cursor = query("select * from user") while (cursor.moveToNext()){ val id = cursor.getInt(0) val name = cursor.getString(1) val lastName = cursor.getString(2) println("id:$id,name;$name,lastName:$lastName") } println("ok") // Prepare for the next version. close() } println("ok-ok") db = helper.runMigrationsAndValidate(TEST_DB, 2, true) db.query("SELECT * FROM user").apply { assertThat(moveToFirst()).isTrue() println(moveToFirst()) println(getLong(getColumnIndex("id"))) // assertThat(getLong(getColumnIndex("id"))).isEqualTo(0) } // Re-open the database with version 2 and provide // MIGRATION_1_2 as the migration process. // db = helper.runMigrationsAndValidate(TEST_DB, 2, true, TestDatabase.MIGRATION_1_2) // MigrationTestHelper automatically verifies the schema changes, // but you need to validate that the data was migrated properly. } @Test fun testAllMigrations() { helper.createDatabase(TEST_DB, 1).apply { close() } Room.databaseBuilder( InstrumentationRegistry.getInstrumentation().targetContext, TestDatabase::class.java, TEST_DB ).addMigrations(TestDatabase.MIGRATION_3_4, TestDatabase.MIGRATION_4_5).build().apply { openHelper.writableDatabase.close() } println("testAllMigrations ok") } } @RunWith(AndroidJUnit4::class) class SimpleEntityReadWriteTest { private lateinit var userDao: UserDao private lateinit var articleDao: ArticleDao private lateinit var db: TestDatabase @Before fun createDb() { val context = ApplicationProvider.getApplicationContext<Context>() db = Room.inMemoryDatabaseBuilder( context, TestDatabase::class.java).addMigrations(TestDatabase.MIGRATION_3_4, TestDatabase.MIGRATION_4_5).build() userDao = db.userDao() articleDao = db.articleDao() // userDao.getAll().forEach(::println) } @After @Throws(IOException::class) fun closeDb() { db.close() } @Test @Throws(Exception::class) fun writeUserAndReadInList() { // val user: User = TestUtil.createUser(3).apply { // setName("george") // } val user = User(null, "11", "44") userDao.insertAll(user) val userList = userDao.getAll() userList.forEach(::println) val article = Article(null,"hi","content1","test") val article2 = Article(null,"hi2","content1","test") articleDao.insertAll(article,article2) articleDao.getAll().forEach(::println) // assertThat(byName.get(0), equalTo(user)) } }
TestDatabase 代码
import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
@Database(entities = [User::class, Article::class, Fruit::class], version = 5, exportSchema = true, autoMigrations = [ AutoMigration(from = 1, to = 2), AutoMigration(from = 2, to = 3)])
abstract class TestDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun fruitDao(): FruitDao
abstract fun articleDao(): ArticleDao
companion object{
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, " +
"PRIMARY KEY(`id`))")
}
}
val MIGRATION_3_4 = object : Migration(3, 4) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("CREATE TABLE IF NOT EXISTS `article` (`id` INTEGER, `title` TEXT, `content` TEXT," +
"PRIMARY KEY(`id`))")
}
}
val MIGRATION_4_5 = object : Migration(4, 5) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("alter table article add column author text")
}
}
}
}
参考文档:https://developer.android.com/training/data-storage/room/migrating-db-versions#kotlin_1
浙公网安备 33010602011771号