【问题标题】:database asset for unitTestunitTest 的数据库资产
【发布时间】:2018-10-16 00:47:35
【问题描述】:

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

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

我试过android-sqlite-asset-helper

val targetContext by lazy { InstrumentationRegistry.getTargetContext() }
val testContext by lazy { InstrumentationRegistry.getContext() }

const val TEST_DB_NAME = "testdb.sqlite"
const val VERSION = 1018

class TestDatabase(context: Context) : 
    SQLiteAssetHelper(context, TEST_DB_NAME, null, null, VERSION) {
    ...  
}

但没有一个上下文有效。使用testContext 无法将数据库写入文件系统,使用targetContext 无法访问androidTest/assets/databases/testdb.sqlite

当我尝试手动复制它时(as suggested by):

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

如何从androidTest/assets/databases/testdb.sqlite 加载数据库?内存加分,因为无论如何我都会在测试后被丢弃。

【问题讨论】:

    标签: android kotlin sqlite integration-testing android-testing


    【解决方案1】:

    我找到了解决办法:

    Convert the database to input-statements

    sqlite testdb.sqlite .dump > testdb.sql
    

    将此文件放入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 语句创建了一个内存数据库。

    这个解决方案并不完美,因为它需要在更新测试数据库时手动执行步骤,但它对我有用。

    【讨论】:

      猜你喜欢
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      相关资源
      最近更新 更多