Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
204 views
in Technique[技术] by (71.8m points)

android - "Unable to open database file" when using SQLiteOpenHelper with instrumentation context

I'm trying to create a database that contains mock objects for testing purposes. I'd prefer to have this db reside in my test package instead of in my application package.

protected class MockObjectOpenHelper extends SQLiteOpenHelper {

    MockObjectOpenHelper() {
        super(instrumentation.getContext(), FILE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        ...
    }
}

When I create my SQLiteOpenHelper from within my app, I pass in the instrumentation context as well as a path that's relative to my test package's database directory. I would think this would allow me to create a database in my test package, but this doesn't seem to be the case. The "databases" directory is never created in my test package.

Is there a way to have my app create and access a database that resides in my test project?

The exception:

14:50:13.917 pool-1-thread-1 android.database.sqlite.SQLiteException: unable to open database file
at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1584)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:638)
at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:659)
at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:652)
at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:482)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
at com.myapp.test.http.DbMockHttpClient.createClientRequestDirector(DbMockHttpClient.java:52)
at com.myapp.test.http.UniversalMockHttpClient.createClientRequestDirector(UniversalMockHttpClient.java:42)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:539)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
E
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I wasn't sissified with @Yves solution because it results in databases created in tested appliction's folder. This can potentially interfere with the application (like purging databases during tests).

I've made some investigations. This error is thrown because "databases" directory fails to be created, and when SQL engine tries to open "databases/dbname.db" file it can't find "databases" folder.

Usually Context is responsible for creating "databases" folder just before creating database for the first time. But it fails because it has invalid permissions. And here is why.

Let's assume Tested project is installed with user app_100, and Tester project is installed with user app_101. When tests are running, the Instrumentation runs using app_100 user, and not app_101. And app_100 has not right to create folder in app_101 private folder.

The easiest way to solve this is to add same value to "android:sharedUserId" int Tester and Tested AndroidManifest.xml. This way both .apk will be installed with same user (in our example this would be app_100).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...