2011-02-23 29 views
5

Sto provando a testare i metodi di inserimento e recupero per la sottoclasse SQLiteOpenHelper in un'applicazione Android. La sottoclasse SQLLiteHelper esiste nell'app sotto test e crea un database nella cartella di installazione. Tuttavia, il test unitario esiste in un InstrumentTestCase nell'app di test e vorrei creare un database di test nell'app di test.Impossibile aprire il database nell'app test Android

Purtroppo, se cerco di creare/aprire un database in applicazione di test, ottengo la seguente eccezione:

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) 

Qualcuno sa perché questo sarebbe fallire?

+1

L'errore indica che non si sta creando il database, o forse lo si sta creando all'esterno di 'SQLiteOpenHelper.onCreate()' (poiché non può essere aperto) e quindi quando si utilizzano altri metodi di convenienza 'SQLiteOpenHelper', essi sono inconsapevoli del tuo database. Inserisci il tuo codice dove crei il database e il tuo 'onCreate' per la sottoclasse' SQLiteOpenHelper'. – RivieraKid

+0

La risposta corretta è questa: http://stackoverflow.com/a/8488722/1432640 – stillwaiting

risposta

4

Io uso il seguente setup() - Metodo della mia 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 + ";"); 
    } 

E 'piuttosto fresco perché la documentazione dice di SQLiteDatabase.create():

creare una memoria sostenuta Database SQLite. Il suo contenuto sarà distrutto quando il database è chiuso.

Così il tuo database test non è persistente e puoi facilmente testare i tuoi metodi di inserimento/aggiornamento/query/cancellazione personalizzati.

Spero che questo aiuti. Se ci sono delle domande, non esitate a chiedere.

Cheers, Christoph

+0

Ehi @Chistoph qual è il metodo wipedata e come posso usarlo per testare le operazioni del database? Grazie – Tony

+0

Ciao @Tony, mi ci è voluto un po ' per trovare il codice da 4 anni fa (la domanda è in realtà 5 anni). Ho aggiornato l'esempio di codice per includere wipeData, dare un'occhiata. L'idea è che ora puoi testare DatabaseHelper senza preoccuparti che ci siano dati rimasti in SQLiteDatabase da altri testrun. –

+0

Grazie mille, lo verificherò – Tony

30

Invece di usare getInstrumentation().getContext() per il contesto nel creare delle aiutante db, ho cambiato in getInstrumentation().getTargetContext() e funziona.

+0

Grazie, ha fatto il trucco! – David

+0

C'è una differenza molto reale tra Instrumentation # getContext() che restituisce il contesto dell'applicazione di test e Instrumentation # getTargetContext() che restituisce il contesto dell'applicazione reale. Ciò significa che l'utilizzo di Instrumentation # getTargetContext #() è rischioso perché i test potrebbero modificare i file effettivamente utilizzati dall'applicazione. –

Problemi correlati