我们有一个SQLite数据库和一个对应的SQLiteOpenHelper
子类。这个助手有一个onDowngrade
我想为其编写Espresso测试的实现。
完整的onDowngrade
实现在这里可用。这是它的简化版本:
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("CREATE TABLE IF NOT EXISTS foo_tmp (_id integer primary key, bar text not null, baz text not null);");
db.execSQL("INSERT INTO foo_tmp(_id,bar,baz) SELECT _id,bar,baz FROM foo;");
db.execSQL("DROP TABLE IF EXISTS foo;");
db.execSQL("RENAME TABLE foo_tmp TO foo;");
}
该测试将加载具有很高版本号以及已添加或已删除列的数据库转储。然后,它将获得一个可读的数据库,并确保该版本已降级为当前的预期版本,并且列名是预期的列名。完整的资源在这里。看起来是这样的:
@Test
public void testMigration() throws IOException {
writeDatabaseFile("database" + File.separator + dbFilename);
InstancesDatabaseHelper databaseHelper = new InstancesDatabaseHelper();
SQLiteDatabase db = databaseHelper.getReadableDatabase();
assertThat(db.getVersion(), is(InstancesDatabaseHelper.DATABASE_VERSION));
List newColumnNames = InstancesDatabaseHelper.getInstancesColumnNames(db);
assertThat(newColumnNames, contains(InstancesDatabaseHelper.CURRENT_VERSION_COLUMN_NAMES));
}
如果我将相同的数据库转储手动加载到应用程序中,则一切都会按预期进行。但是,当我运行此测试时,看起来RENAME
迁移中的最后一个未执行。如果我注释掉迁移中的最后两个SQL语句(删除原始表并将临时表重命名为原始表名),则可以断言临时表具有预期的内容(这是一个显示此内容的提交)。
通过一些实验,我们发现databaseHelper.getReadableDatabase().close();
在实例化SQLiteOpenHelper
使测试通过之后添加测试。鉴于该onDowngrade
呼叫已封装在事务中,所以我不知道这是怎么可能的。
这是否表明我们的onDowngrade
实现存在错误?在Espresso测试中触发迁移是否有所不同?