【发布时间】:2020-09-15 16:58:04
【问题描述】:
我正在尝试测试 Room 迁移,但测试总是失败。模型甚至没有变化。我只增加了版本号,迁移为空——测试仍然失败。我不明白我做错了什么。
假设我们有一个实体EntityExample,有两列a 和b。主键由a 和b 组成,我们对两列都有索引。代码如下:
@Entity(primaryKeys = {"a", "b"}, indices = {@Index("a"), @Index("b")})
public class EntityExample {
@NonNull public Long a;
@NonNull public Long b;
}
此外,我们在版本 1 中的数据库:
@Database(version=1,entities={EntityExample.class})
public abstract class DBExample extends RoomDatabase {
}
在版本 2 中:
@Database(version=2,entities={EntityExample.class})
public abstract class DBExample extends RoomDatabase {
}
还有迁移:
public class MigrationExample {
public final static Migration MIGRATION_1_2 = new Migration(1,2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
}
};
}
为了在测试中访问架构,在 build.gradle 中添加了:
android {
sourceSets {
// Adds exported schema location as test app assets.
debug.assets.srcDirs += files("$projectDir/schemas".toString())
}
}
最后是测试:
@Config(sdk = Build.VERSION_CODES.O_MR1)
@RunWith(RobolectricTestRunner.class)
public class MigrationExampleTest {
@Rule
public MigrationTestHelper helper;
public MigrationExampleTest() {
helper = new MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
DBExample.class.getCanonicalName(),
new FrameworkSQLiteOpenHelperFactory());
}
@Test
public void migrationTest() throws IOException {
SupportSQLiteDatabase dbV1 = helper.createDatabase("migration-test", 1);
dbV1.close();
DBExample dbV2 = Room.databaseBuilder(
InstrumentationRegistry.getInstrumentation().getTargetContext(),
DBExample.class,
"migration-test")
.addMigrations(MigrationExample.MIGRATION_1_2)
.build();
dbV2.getOpenHelper().getWritableDatabase();
dbV2.close();
}
}
测试在dbV2.getOpenHelper().getWritableDatabase(); 行失败
java.lang.IllegalStateException: Migration didn't properly handle: EntityExample(....EntityExample).
Expected:
TableInfo{name='EntityExample', columns={a=Column{name='a', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, b=Column{name='b', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=2, defaultValue='null'}}, foreignKeys=[], indices=[Index{name='index_EntityExample_a', unique=false, columns=[a]}, Index{name='index_EntityExample_b', unique=false, columns=[b]}]}
Found:
TableInfo{name='EntityExample', columns={a=Column{name='a', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, b=Column{name='b', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}}, foreignKeys=[], indices=null}
如您所见(向右滚动测试输出时),找到的 TableInfo 中缺少 indices 部分。此外,b 的 primaryKeyPosition 在 1 和 2 之间有所不同。我不明白为什么,我不知道究竟是什么导致了测试失败,也不知道如何解决这。运行应用程序有效,不会引发异常。我检查了模式,除了更新的版本号(参见https://justpaste.it/68l2b 和https://justpaste.it/3r45p)之外,它们完全一样。但是,测试失败了!
【问题讨论】:
-
我也有同样的问题。使用 SQL 语句创建索引不起作用,因为它们没有显示在 TableInfo 中,所以我的迁移测试也总是失败。
标签: java android sqlite android-room database-migration