Android unitTest的数据库资产

Android unitTest的数据库资产,android,kotlin,sqlite,integration-testing,android-testing,Android,Kotlin,Sqlite,Integration Testing,Android Testing,对于我的单元测试,我在SQLite数据库中收集了真实世界的传感器数据。我需要这些数据来创建我的测试。我尝试了下面两种方法,但没有成功 我真的被这个问题难住了,因为通常SQLiteOpenHelper会完美地加载/data/data/packageName/databases/中的任何数据库 我试过: 但这些上下文都不起作用。使用testContext无法将数据库写入文件系统,使用targetContext无法访问androidTest/assets/databases/testdb.sqlite

对于我的单元测试,我在SQLite数据库中收集了真实世界的传感器数据。我需要这些数据来创建我的测试。我尝试了下面两种方法,但没有成功

我真的被这个问题难住了,因为通常
SQLiteOpenHelper
会完美地加载
/data/data/packageName/databases/
中的任何数据库

我试过:

但这些上下文都不起作用。使用
testContext
无法将数据库写入文件系统,使用
targetContext
无法访问
androidTest/assets/databases/testdb.sqlite

当我尝试手动复制它()时,使用:

如何从
androidTest/assets/databases/testdb.sqlite
加载数据库?内存中的奖励积分,因为在测试后我将以任何方式被丢弃。

我找到了一个解决方案:

将此文件放入
androidTest/assets/databases/
中,然后创建数据库:

    class MyDatabaseOpenHelper(val context: Context,
                           version: Int = 1) : SQLiteOpenHelper
                                                  (context,
                                                   null,
                                                   null,
                                                   version,
                                                   null) {
    override fun onCreate(db: SQLiteDatabase?) {
        BufferedReader(InputStreamReader(context.getAssets().open("databases/testdb.sql"))).apply {
            lines().forEach {
                try {
                    db!!.execSQL(it)
                } catch (e: SQLiteException) {
                    Log.w("read test db", e)
                }
            }
            close()
        }
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        //noop load from file
    }
}
通过不提供名称,我们可以从sql语句创建内存中的数据库

这个解决方案并不完美,因为它需要在更新测试数据库时手动执行一个步骤,但对我来说是可行的

const val DB_PATH = "/data/data/de.leo.smartTrigger/databases/"

@Throws(IOException::class)
private fun copyDatabase(testContext: Context) {
    val inputStream = testContext.getAssets().open("databases/$TEST_DB_NAME")
    val outFileName = DB_PATH + TEST_DB_NAME
    val outputStream = FileOutputStream(outFileName)

    val buffer = ByteArray(1024)
    var length: Int = inputStream.read(buffer)
    while (length > 0) {
        outputStream.write(buffer, 0, length)
        length = inputStream.read(buffer)
    }

    outputStream.flush()
    outputStream.close()
    inputStream.close()
}

//after
copyDatabase(testContext)
val db = SQLiteDatabase.openDatabase(DB_PATH + TEST_DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY)
//yields an empty database although 
File(DB_PATH + TEST_DB_NAME).exists() == true // true
sqlite testdb.sqlite .dump > testdb.sql
    class MyDatabaseOpenHelper(val context: Context,
                           version: Int = 1) : SQLiteOpenHelper
                                                  (context,
                                                   null,
                                                   null,
                                                   version,
                                                   null) {
    override fun onCreate(db: SQLiteDatabase?) {
        BufferedReader(InputStreamReader(context.getAssets().open("databases/testdb.sql"))).apply {
            lines().forEach {
                try {
                    db!!.execSQL(it)
                } catch (e: SQLiteException) {
                    Log.w("read test db", e)
                }
            }
            close()
        }
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        //noop load from file
    }
}