0

我有以下两个用于数据库操作的类。

public class BlackboxSQLiteDatabase implements BlackboxDatabase {

    private Context context;
    private SQLiteDatabase sqliteDatabase;
    private String databaseName;
    public static final String IN_MEMORY_DATABASE = null;
    private final String SECRET_KEY = "dm13YXJlY";

    public BlackboxSQLiteDatabase(Context context, String databaseName, int version) {
        this.context = context;
        this.databaseName = databaseName;
        SQLiteDatabase.loadLibs(context);
        SQLiteOpenHelper openHelper = new BlackboxSQLiteOpenHelper(context, databaseName, version);
        this.sqliteDatabase = openHelper.getWritableDatabase(SECRET_KEY);
    }

    @Override
    public void beginTransaction() {
        sqliteDatabase.beginTransaction();
    }

    @Override
    public void setTransactionSuccessful() {
        sqliteDatabase.setTransactionSuccessful();
    }

    @Override
    public void endTransaction() {
        sqliteDatabase.endTransaction();
    }

    @Override
    public int getVersion() {
        return sqliteDatabase.getVersion();
    }

    @Override
    public void execSQL(String statement) {
        sqliteDatabase.execSQL(statement);
    }

    @Override
    public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
        return sqliteDatabase.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
    }

    @Override
    public long insert(String table, String nullColumnHack, ContentValues values) {
        return sqliteDatabase.insert(table, nullColumnHack, values);
    }

    @Override
    public int delete(String table, String whereClause, String[] whereArgs) {
        return sqliteDatabase.delete(table, whereClause, whereArgs);
    }

    @Override
    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
        return sqliteDatabase.update(table, values, whereClause, whereArgs);
    }

    private static final String DROP_TABLE = "DELETE FROM %s ;";
    public void deleteAllData() {
        if (isTestStubDatabase()) {
            return;
        }

        try {
            sqliteDatabase.beginTransaction();
            for (TableSchema tableSchema : BlackboxDatabaseSchema.TABLE_SCHEMAS) {
                String dropCommand = String.format(DROP_TABLE, tableSchema.getTableName());
                sqliteDatabase.execSQL(dropCommand);
            }
            sqliteDatabase.setTransactionSuccessful();
        } finally {
            sqliteDatabase.endTransaction();
        }
    }

    private boolean isTestStubDatabase() {
        return databaseName == IN_MEMORY_DATABASE;
    }

}

public class BlackboxSQLiteOpenHelper extends SQLiteOpenHelper {

    public BlackboxSQLiteOpenHelper(Context context, String name, int version) {
        super(context, name, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        for (TableSchema tableSchema : BlackboxDatabaseSchema.TABLE_SCHEMAS) {
            db.execSQL(tableSchema.getCreateStatement());
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        throw new UnrecoverableException("TODO: implement database upgrade");
    }

}

然后我正在尝试为 deleteAllData() 方法编写单元测试

public class BlackboxSQLiteDatabaseTests extends InstrumentationTestCase {

    public static final String IN_MEMORY_DATABASE = null;
    private Context context;
    private BlackboxClient blackboxClient;
    private BlackboxDatabase database;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
         /* https://code.google.com/p/dexmaker/issues/detail?id=2
        *  Observing an error on my Nexus 6P without below fix
        *  java.lang.IllegalArgumentException: dexcache == null
        *  (and no default could be found; consider setting the 'dexmaker.dexcache' system property)
        */
        System.setProperty("dexmaker.dexcache",
                getInstrumentation()
                        .getTargetContext()
                        .getCacheDir()
                        .getPath());
        context = getInstrumentation().getTargetContext();
        database = new BlackboxSQLiteDatabase(context, "config.db", 1);

    }

    public void testDeleteAllData() {
        //test code
     }

}

然后在运行单元测试时出现此错误。

net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: create locale table failed
at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2474)
at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2338)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1087)
at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1150)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:162)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:129)
at com.mc.gc.storage.BlackboxSQLiteDatabase.<init>(BlackboxSQLiteDatabase.java:35)
at com.mc.gc.storage.BlackboxSQLiteDatabaseTests.setUp(BlackboxSQLiteDatabaseTests.java:44)

我肯定每次都使用相同的密钥来打开数据库,因为它是常量。有人可以指出这里可能出现的问题。每次运行测试代码时都会遇到相同的错误。

4

1 回答 1

0

I had a stale copy of the app in the device which was causing the issue. I uninstalled and remove all old copies and the test seems to be working. Sorry for the trouble guys.

于 2016-01-28T15:54:12.813 回答