Test de code Android avec JUnit et le JDK

J’écris des tests POJO pour mon code Android.

Je veux les exécuter localement avec le JDK (pas avec Dalvik sur l’émulateur) – pour la vitesse, JUnit 4, Mockito et pouvoir fonctionner sans tête sans périphérique – j’ai donc un projet “Java” distinct dans Eclipse.

Si la méthode que je teste fait référence à quelque chose à partir du SDK Android, par exemple, android.util.Log , le test échoue – cela est logique car android.jar ne figure pas dans le chemin d’access aux classes. Pour reproduire j’ai ce cas de test:

 public class FooTests { @Test public void testFoo() { android.util.Log.d("x", "y"); } } 

Si j’ajoute explicitement android.jar au chemin de classe du projet test, des exceptions telles que

 java.lang.RuntimeException: Stub! at android.util.Log.d(Log.java:7) at com.example.FooTests.testFoo(FooTests.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ... at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

Existe-t-il un moyen de faire fonctionner le code sans se moquer de toutes les dépendances du SDK Android? Peut-être un android.jar existe-t-il déjà?

EDIT : Pour l’instant, j’ai fini par intégrer des classes telles que android.util.Log et les injecter dans les instances, pour des tests classiques basés sur IOC. La suggestion de Scott PowerMock est ma prochaine étape lorsque j’en aurai besoin.

Plus tard : Robolecsortingc !

À ma connaissance, il n’y a pas d’android.jar ridiculisé. J’utilise Powermock pour tout simuler. Une chose que vous pouvez faire pour vous aider à vous moquer lourdement est de fluidifier vos classes androïdes étendues telles que l’activité, les fragments, les diffuseurs, etc. et de les déléguer à des classes pojo. Vous pouvez prendre une décision basée sur le risque, qui consiste à ne pas tester les classes étendues android par un test d’isolement, mais plutôt à les tester par le biais du framework de test android ou de quelque chose comme Robotium.

Pour les véritables tests unitaires d’isolation sous Android, pour moi, les tests unitaires sur java jvm mocking de toutes les classes qui collaborent sont la meilleure solution.

J’ai eu le même problème. Je voulais tester des POJO simples localement.
Plus précisément, mon code voulait utiliser android.util.Base64.
J’ai fini par utiliser le SDK pour installer les sources d’Android 4, puis de copier la classe android.util.Base64 dans mon projet.
Curieusement, cela a fonctionné.

J’ai eu le même problème. Je voulais tester la logique métier simple localement. Plus précisément, mon code utilise android.util.SparseArray .

J’ai essayé 3 approches différentes pour le rendre testable avec Junit en dehors d’Android.

  • Dans ma logique métier, j’ai créé une interface que j’ai liée à MySparseArray qui hérite de SparseArray . Dans le test Junit, j’ai ré-implémenté l’interface en utilisant HashMap . Cela fonctionne, mais à long terme, il rest trop de travail pour rendre la logique métier testable par unité si d’autres android.* Sont nécessaires.
  • Comme suggéré par @Tal Weiss, j’ai ajouté les sources Java android des classes requirejses: android.util.SparseArray.java qui utilise com.android.internal.util.ArrayUtils.java . Cela fonctionne aussi, mais je n’aime pas append plus de sources Android, surtout s’il y a beaucoup plus de dépendances.
  • J’ai téléchargé un fichier binary gratuit android.jar pour un ancien Android 2.2 à partir de http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1 et l’a inclus. comme lib dans mon projet junit-java. Ce dalvik.* contient uniquement des classes pour les espaces de noms android.* , com.android.* , dalvik.* Et framework.base.* . Cela fonctionne aussi.

Actuellement, j’ai réussi à éviter d’utiliser les classes android.* exception de SparseArray dans ma couche de SparseArray et ne dépend pas du contexte, de l’activité ou du service. J’aurais pu utiliser HashMap dans la couche Android-Business au lieu de SparseArray .

Unmock-plugin pourrait aider https://github.com/bjoernQ/unmock-plugin . Dans mon cas, cela fonctionne avec SparseArray.

Les tests android / junit intégrés ne feront-ils pas ce que vous voulez?