Les tests de base de données SQLite dans Robolectric
Je suis en train de tester une simple base de données SQLite en utilisant Robolectric dans mon application Android. Je suis en train de mettre en certaines valeurs, mais lors de la lecture de retour 0 lignes sont retournées.
Je suis en utilisant le SQLiteOpenHelper classe pour accéder à la base de données.
// 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
Lors du débogage du code de l'extérieur robolectric cela fonctionne comme prévu. Suis-je en train de faire quelque chose de mal ou n'est-il pas possible de tester les bases de données SQlite en utilisant Robolectric?
- Vérifier ce code fonctionne???????/ stackoverflow.com/questions/6283834/...
Vous devez vous connecter pour publier un commentaire.
NOTE: Cette réponse est obsolète. Si vous utilisez Roboletric 2.X, veuillez consulter https://stackoverflow.com/a/24578332/850787
Le problème est que Robolectric de SQLiteDatabase est stocké uniquement dans la
de la mémoire, de sorte que lorsque vous appelez getReadableDatabase ou getWritableDatabase,
la base de données existante sera remplacée par la nouvelle base de données vide.
J'ai été en cours d'exécution pour le même problème et la seule solution que j'ai trouvé
était que j'avais besoin de la fourche à la Robolectric projet et a ajouté
ShadowSQLiteOpenHelper pour enregistrer la base de données même si le contexte est donné deux
fois. Toutefois, le problème avec ma fourche, c'est que j'ai eu à "désactiver"
close()-fonction lorsque contex est donné parce que sinon
Connexion.close() va détruire la base de données en mémoire. J'ai fait des pull request pour lui, mais il n'est pas fusionné pour projet encore.
Mais n'hésitez pas à cloner mon version et cela devrait résoudre votre problème (Si je
bien compris 😛 ).
Il peut être trouvé sur GitHub: https://github.com/waltsu/robolectric
Ici est un exemple, comment utiliser la modification:
Bien sûr, vous n'avez pas besoin de créer de nouveaux SQLiteOpenHelper, mais c'est juste l'exemple que le passage même contexte à deux SQLiteOpenHelper donnera la même base de données.
db = cache.getReadableDatabase();
de l'OP de code de la référence initiale est réutilisé?Robolectric 2.3 utilise une réelle mise en œuvre de SQLite à la place d'une collection d'ombres et de faux. Les Tests peuvent désormais être écrit pour vérifier la base de données réelle comportement.
Le code lié à la accepté de répondre ne fonctionne pas pour moi; il peut être mis à jour. Ou peut-être ma configuration est juste différent. Je suis à l'aide de Robolectric 2.4 de l'instantané, ce qui ne semble pas inclure un ShadowSQLiteOpenHelper, à moins que j'ai raté quelque chose. En tout cas, j'ai trouvé une solution. Voici ce que j'ai fait:
@Config( shadows = { ShadowSQLiteOpenHelper.class } )
. Pas besoin d'un custom test (test personnalisé coureur.new Activity()
que le Contexte (Robolectric heureux qui s'en occupe), et utilisé par l'habitude.Maintenant, en ce moment, j'ai remarqué qu'un véritable fichier de base de données a été se créé localement: après la première exécution d'un test qui a utilisé mon SQLiteOpenHelper sous-classe, j'ai continué à obtenir une SQLiteException sur les tests ultérieurs, car ma table existait déjà; et j'ai pu voir un fichier appelé "chemin" et un fichier appelé "path-journal" assis dans mon dépôt local. Ce qui me confond, car j'étais sous l'impression que l'ombre de classe a à l'aide d'une base de données en mémoire.
Il s'avère que la ligne incriminée dans l'ombre de la classe est:
dans les deux getReadableDatabase() et getWriteableDatabase(). Je savais que le réel SQLiteOpenHelper pourrait créer une base de données en mémoire, et après avoir regardé à la source pour voir comment c'est fait, j'ai remplacé la ligne ci-dessus avec:
après quoi, tout semble fonctionner. Je suis en mesure d'insérer des lignes et de les lire.
J'espère que cela aide quelqu'un d'autre.
Une chose bizarre qui m'est arrivé à moi qui n'est pas exactement liée à cette question, mais peut aider quelqu'un, c'est que je suis également en utilisant jmockit, et j'avais utilisé dans un test dans la même classe; mais pour une raison quelconque, ce la cause de mon personnalisée de l'ombre de la classe à ne pas être utilisé. Je suis passé à Mockito pour juste que la classe, et il fonctionne très bien.