Tests unitaires Android nécessitant un contexte

J’écris mon premier backend de firebase database Android et j’ai du mal à tester la création de ma firebase database.

Actuellement, le problème que je rencontre est l’obtention d’un object Context valide à transmettre à mon implémentation de SQLiteOpenHelper. Est-il possible d’obtenir un object Context dans une classe qui étend TestCase? La solution à laquelle j’ai pensé consiste à instancier une activité dans la méthode d’installation de mon TestCase, puis à atsortingbuer le contexte de cette activité à une variable de champ à laquelle mes méthodes de test peuvent accéder … mais il semble que la solution soit plus simple.

Merci pour votre consortingbution!

Macy

Vous pouvez essayer de passer à AndroidTestCase . En regardant les documents, il semble qu’il devrait pouvoir vous fournir un contexte valide à transmettre à SQLiteOpenHelper.

Edit: N’oubliez pas que vous devez probablement installer vos tests dans un “Android Test Project” dans Eclipse, car les tests tenteront de s’exécuter sur l’émulateur (ou le périphérique réel).

Si vous exécutez vos tests avec AndroidJUnit4 , vous pouvez utiliser InstrumentationRegistry méthodes InstrumentationRegistry pour obtenir un contexte:

InstrumentationRegistry.getTargetContext() – fournit le Context de l’application cible.

InstrumentationRegistry.getContext() – fournit le Context du package de cette instrumentation.

L’utilisation de la AndroidTestCase:getContext() ne donne qu’un contexte de stub dans mon expérience. Pour mes tests, j’utilise une activité vide dans mon application principale et j’obtiens le Context via cette application. Étend également la classe de suite de tests avec la classe ActivityInstrumentationTestCase2 . Semble travailler pour moi.

 public class DatabaseTest extends ActivityInstrumentationTestCase2 EmptyActivity activity; Context mContext = null; ... @Before public void setUp() { activity = getActivity(); mContext = activity; } ... //tests to follow } 

Que font les autres?

Vous devez utiliser ApplicationTestCase ou ServiceTestCase.

Vous pouvez dériver de MockContext et retourner par exemple un MockResources sur getResources() , un ContentResolver valide sur getContentResolver() , etc.

L’alternative consiste à exécuter par exemple Robolecsortingc qui simule un système d’exploitation Android entier. Ceux-ci seraient pour les tests du système : c’est beaucoup plus lent à exécuter.

Étendre AndroidTestCase et appeler AndroidTestCase: getContext () a bien fonctionné pour que j’utilise Context et que je l’utilise avec une firebase database SQLite.

Le seul inconvénient est que la firebase database qu’elle crée et / ou utilise sera la même que celle utilisée par l’application de production. Vous souhaiterez probablement utiliser un nom de fichier différent pour les deux.

par exemple.

  public static final Ssortingng NOTES_DB = "notestore.db"; public static final Ssortingng DEBUG_NOTES_DB = "DEBUG_notestore.db"; 

Première classe de test sous (androidTest).

Utilisez maintenant le code suivant:

 public class YourDBTest extends InstrumentationTestCase { private DBContracts.DatabaseHelper db; private RenamingDelegatingContext context; @Override public void setUp() throws Exception { super.setUp(); context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_"); db = new DBContracts.DatabaseHelper(context); } @Override public void tearDown() throws Exception { db.close(); super.tearDown(); } @Test public void test1() throws Exception { // here is your context context = context; }} 

Une solution alternative consiste à éviter l’utilisation d’ ApplicationTestCase ou d’ AndroidTestCase ou de toute autre classe dépendant du Context . Le fait est qu’il n’est pas nécessaire de tester le framework SQLite ou ORM pour pouvoir créer une interface avec les méthodes CRUD base:

 public interface UsersManager{ User createUser(Ssortingng userId); User getUser(Ssortingng userId); boolean updateUser(User user); boolean deleteUser(User user); } 

Et implémenter deux versions: une pour les tests et une autre pour l’exécution de la production. La version pour les tests pourrait être facilement implémentée avec HashMap :

 public class TestUsersManager implements UsersManager{ private HashMap users = new HashMap(); public User createUser(Ssortingng userId){ User result = new User(userId); users.put(userId, user); return result; } //... other methods } 

Il fonctionne rapidement (pas de disque IO en cas de SQLite ) et ne comporte pas de dépendances externes. Au fait, il s’agit également d’un niveau d’abstraction supplémentaire: pour le code de production, par exemple, vous pouvez facilement basculer entre les frameworks ORM .