JPM*_*JPM 5 android unit-testing android-room
尝试使用 MigrationTestHelper 类和 Robolectric 测试房间迁移。我们希望将其作为 JUnit 测试,因为我们的 CI 环境无法启动模拟器。 (请不要为模拟器提供 CI 修复的答案,CI 不在我的控制范围内)我 唯一的问题是测试失败,因为它找不到模式。我的 build.gradle 已经有这个了
android {
sourceSets {
test.assets.srcDirs += files("$projectDir/schemas".toString())
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
test {
java.srcDirs += "$projectDir/src/sharedTest/java"
}
testOptions {
unitTests {
includeAndroidResources = true
}
unitTests.all {
systemProperty 'robolectric.enabledSdks', '21'
}
}
}
dependencies {
// has all the proper dependencies from mockito adn robolectric to kotlin and junit.
}
Run Code Online (Sandbox Code Playgroud)
这是测试代码,但同样主要是在调用数据库创建时找不到模式。json 文件也在架构目录中
@RunWith(RobolectricTestRunner::class)
class Migration19To20Test {
private val migration = MyDatabase.MIGRATION_19_20
private val fromVersion = 19
private val toVersion = 20
@get:Rule
val helper: MigrationTestHelper = MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
MyDatabase::class.java.canonicalName,
FrameworkSQLiteOpenHelperFactory())
private val testDatabaseName = "migration-test"
@Test
fun insertsFirmwareVersionFullColumn() {
givenADatabase()
val validateDroppedTables = true
val db = helper.runMigrationsAndValidate(
testDatabaseName,
toVersion,
validateDroppedTables,
migration)
db.query("select * from ${DatabaseConstants.Table.People}").use { cursor ->
cursor.moveToFirst()
assertTrue("table should contain the ${DatabaseConstants.Column.People.NAME_FULL} column as it should have been added",
cursor.columnNames.contains(DatabaseConstants.Column.People.NAME_FULL))
}
}
private fun givenADatabase() {
// Test fails here
helper.createDatabase(testDatabaseName, fromVersion)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 0
我通过复制MigrationTestHelper到我的测试源代码并修改 loadSchema 方法来解决它,如下所示
private SchemaBundle loadSchema(Context context, int version) throws IOException {
// InputStream input = context.getAssets().open(mAssetsFolder + "/" + version + ".json");
InputStream input = new FileInputStream("./schemas/" + mAssetsFolder + "/" + version + ".json");
return SchemaBundle.deserialize(input);
}
Run Code Online (Sandbox Code Playgroud)
该schemas目录在build.gradle中配置
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation" : "$projectDir/schemas".toString(),
"room.incremental" : "true",
"room.expandProjection": "true"]
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,原因是此类在目录中查找迁移,assets因为 Google 假设您将在设备上运行这些迁移。在这种情况下,您必须将它们作为 Android 资产的一部分包含在内。
使用 Robolectric,它只是从目录中读取并将其放入流中。