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.
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. 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. 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?