2011-02-23 33 views
5

我想在Android應用程序中測試我的SQLiteOpenHelper子類的插入和檢索方法。 SQLLiteHelper子類存在於被測試的應用程序中,並在安裝文件夾中創建一個數據庫。但是,單元測試存在於測試應用程序中的InstrumentTestCase中,我想在測試應用程序中創建測試數據庫。無法在Android測試應用程序中打開數據庫

不幸的是,如果我嘗試建立/測試程序打開一個數據庫,我得到以下異常:

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.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:168) 
at com.kizoom.android.mybus.storage.MyStopsDatabase.getMyStops(MyStopsDatabase.java:63) 
at com.kizoom.mybus.test.MyStopsDatabaseTest.testGetMyStops(MyStopsDatabaseTest.java:24) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:191) 
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:181) 
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:164) 
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:151) 
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:425) 
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1520) 

The following information appears in LogCat. 

02-21 11:52:16.204: ERROR/Database(1454): sqlite3_open_v2("/data/data/com.kizoom.mybus.test/databases/MyStops", &handle, 6, NULL) failed 

02-21 11:52:16.204: ERROR/SQLiteOpenHelper(1454): Couldn't open MyStops for writing (will try read-only): 

02-21 11:52:16.204: ERROR/SQLiteOpenHelper(1454): android.database.sqlite.SQLiteException: unable to open database file 

02-21 11:52:16.204: ERROR/SQLiteOpenHelper(1454):  at android.database.sqlite.SQLiteDatabase.dbopen(Native Method) 

02-21 11:52:16.204: ERROR/SQLiteOpenHelper(1454):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1584) 

02-21 11:52:16.204: ERROR/SQLiteOpenHelper(1454):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:638) 

有誰知道爲什麼會失敗?

+1

錯誤提示您沒有創建數據庫 - 或者可能是在SQLiteOpenHelper.onCreate()之外創建它(因爲它無法打開),因此當您使用其他SQLiteOpenHelper方便的方法時,不知道你的數據庫。請將您的代碼發佈到創建數據庫的位置,並將您的子類「SQLiteOpenHelper」的'onCreate'發佈。 – RivieraKid

+0

正確答案是這樣的:http://stackoverflow.com/a/8488722/1432640 – stillwaiting

回答

4

我用下面的設置() - 方法,我TestDatabaseHelper * -TestCases:

@Override 
    protected void setUp() throws Exception { 
     super.setUp(); 
     final SQLiteDatabase db = SQLiteDatabase.create(null); 
     Context context = new MockContext() { 
      @Override 
      public SQLiteDatabase openOrCreateDatabase(String file, int mode, SQLiteDatabase.CursorFactory factory) { 
       return db; 
      }; 
     }; 
     mHelper = new MyCustomSubclassOfDatabaseHelper(context); 
     mDb = mHelper.getWritableDatabase(); 
     wipeData(mDb); 
    } 
    public void wipeData(SQLiteDatabase db) { 
     db.execSQL("DELETE FROM " + TABLENAME + ";"); 
    } 

,因爲文件說,大約SQLiteDatabase.create()這是很酷:

創建支持的內存SQLite數據庫。數據庫關閉時,其內容將被銷燬 。

因此,您的testdatabase不會持久化,您可以輕鬆測試您的自定義插入/更新/查詢/刪除方法。

希望這會有所幫助。如果還有任何問題,請隨時提問。

乾杯, 克里斯托夫

+0

嗨@Chistoph什麼是Wiipedata方法,以及如何使用它來測試數據庫操作?謝謝 – Tony

+0

嗨@Tony,花了我一段時間從4年前找到代碼(問題實際上是5歲)。 我更新了代碼示例以包含wipeData,看一看。 這個想法是,您現在可以測試DatabaseHelper,而不用擔心SQLiteDatabase中有其他testruns中存在數據。 –

+0

非常感謝,我確認了! – Tony

30

而不是使用getInstrumentation().getContext()爲DB助手的創建過程中的情況下,我把它改成getInstrumentation().getTargetContext()和它的作品。

+0

謝謝! – David

+0

Instrumentation#getContext()返回測試應用程序的上下文,Instrumentation#getTargetContext()返回實際應用程序的上下文。這意味着使用Instrumentation#getTargetContext#()會有風險,因爲您的測試可能會修改應用程序實際使用的文件。 –