Testen der SQLite-Datenbank in Robolectric
Ich versuche zu testen, eine einfache SQLite-Datenbank mit Robolectric in meiner Android-Anwendung. Ich bin putting in einige Werte, aber wenn Sie zu Lesen wieder 0 Zeilen zurückgegeben werden.
Ich bin über die SQLiteOpenHelper Klasse auf die Datenbank zugreifen.
// RequestCache extends SQLiteOpenHelper
RequestCache cache = new RequestCache(activity);
SQLiteDatabase db = cache.getWritableDatabase();
// Write to DB
ContentValues values = new ContentValues();
values.put(REQUEST_TIMESTAMP, TEST_TIME);
values.put(REQUEST_URL, TEST_URL);
db.insertOrThrow(TABLE_NAME, null, values);
// Read from DB and compare values
Vector<Request> matchingRequests = new Vector<Request>();
db = cache.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, SEARCH_URL_RETURN_COLUMNS, SEARCH_URL_WHERE, new String[] {url}, null, null, ORDER_BY, null);
int id = 0;
while(cursor.moveToNext()) {
long timestamp = cursor.getLong(0);
Request request = new Request(id++);
request.setUrl(url);
request.setCreationTimestamp(new Date(timestamp));
matchingRequests.add(request);
}
// Assert that one row is returned
assertThat(matchingRequests.size(), equalTo(1)); // fails, size() returns 0
Beim Debuggen des Codes außerhalb robolectric dies funktioniert wie erwartet. Mache ich etwas falsch oder ist es nicht möglich zu testen, SQlite-Datenbanken mit Robolectric?
InformationsquelleAutor der Frage Kjetil Eide | 2011-09-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
HINWEIS: Diese Antwort ist veraltet. Wenn Sie mit Roboletric 2.X, bitte siehe https://stackoverflow.com/a/24578332/850787
Das problem ist, dass Robolectric ist SQLiteDatabase gespeichert ist, nur in
Speicher, so dass, wenn Sie nennen getReadableDatabase oder getWritableDatabase,
die vorhandene Datenbank wird überschrieben mit neuen leeren Datenbank.
War ich laufen, um das gleiche problem und die einzige Lösung, die ich gefunden
war, dass ich brauchte, um die Gabel Robolectric Projekt und das Hinzugefügt
ShadowSQLiteOpenHelper zu Datenbank speichern, wenn gleiche Zusammenhang ist gegeben, zwei
mal. Aber das problem mit meiner Gabel, die ich hatte, um 'deaktivieren'
close()-Funktion, wenn contex ist gegeben, weil sonst
- Verbindung.close() zerstört die Datenbank im Arbeitsspeicher. Ich habe aus pull-Anfrage für ihn, aber es ist nicht verschmolzen Projekt noch.
Aber fühlen Sie sich frei, um mein Klon-version und es sollte dein problem lösen (Wenn ich
es richtig verstanden 😛 ).
Es ist auf GitHub zu finden: https://github.com/waltsu/robolectric
Hier ist ein Beispiel, wie Sie mithilfe der Modifikation:
Natürlich Sie nicht brauchen, um erstellen Sie neue SQLiteOpenHelper, aber das ist nur eine Beispiel, das die übergabe gleichen Kontext zwei unterschiedliche SQLiteOpenHelper geben wird dieselbe Datenbank.
InformationsquelleAutor der Antwort Waltsu
Robolectric 2.3 verwendet einer echten Implementierung der SQLite anstatt eine Sammlung von Schatten und Fälschungen. Tests können nun geschrieben werden, um zu überprüfen, Reale Verhalten der Datenbank.
InformationsquelleAutor der Antwort Jevgenij Evll
Dem code verknüpft die akzeptierte Antwort hat bei mir nicht funktioniert; es können veraltet sein. Oder vielleicht ist mein setup ist einfach anders. Ich bin mit Robolectric 2.4 Momentaufnahme, die nicht scheinen, um eine ShadowSQLiteOpenHelper, es sei denn, ich habe etwas verpasst. Auf jeden Fall habe ich herausgefunden, eine Lösung. Hier ist, was ich getan habe:
@Config( shadows = { ShadowSQLiteOpenHelper.class } )
. Keine Notwendigkeit für einen benutzerdefinierten test-runner.new Activity()
wie der Kontext (Robolectric gerne übernimmt), und verwendet es gewohnt.Nun, an diesem Punkt, ich habe bemerkt, dass eine eigentliche Datenbank-Datei war immer lokal erstellt wurde: nach dem ersten Lauf ein test, der verwendet meine SQLiteOpenHelper Unterklasse, ich habe immer ein SQLiteException auf spätere tests, weil meine Tabelle schon existiert, und ich konnte sehen, eine Datei namens "Pfad" und eine Datei namens "path-journal" sitzen in meinem lokalen repository. Das verwirrte mich, da ich war unter den Eindruck, dass der shadow-Klasse wurde mit einer in-memory-Datenbank.
Es stellt sich heraus, die betreffende Zeile in der shadow-Klasse:
in beiden getReadableDatabase() und getWriteableDatabase(). Ich wusste, dass die realen SQLiteOpenHelper eine in-memory-Datenbank, und nach einem Blick auf die Quelle, um zu sehen, wie es geht, ersetzt habe ich die oben genannte Zeile mit:
nach denen alles zu funktionieren scheint. Ich bin in der Lage, Zeilen einfügen und Lesen Sie diese wieder.
Hoffentlich hilft jemand anderes.
Eine seltsame Sache, die mir passiert ist, das nicht genau auf diese Frage beziehen, aber vielleicht helfen Sie jemandem weiter, ist, dass ich auch mit jmockit, und ich hatte es in einem test in der gleichen Klasse, aber für einige Grund, dies verursacht meine custom shadow-Klasse nicht verwendet werden. Ich wechselte zu Mockito nur für diese Klasse, und es funktioniert gut.
InformationsquelleAutor der Antwort Kevin