Prueba del código de Android con JUnit y el JDK

Estoy escribiendo algunas pruebas de POJO para mi código de Android.

Quiero ejecutarlos localmente con el JDK (no con Dalvik en el emulador) – por velocidad, JUnit 4, Mockito, y ser capaz de ejecutar decapitado sin un dispositivo – por lo que tengo un proyecto "Java" separado en Eclipse.

Si el método que estoy probando pasa a hacer referencia a cualquier cosa desde el SDK de Android, por ejemplo, android.util.Log , la prueba falla – esto tiene sentido porque android.jar no está en el classpath. Para reproducir Tengo este caso de prueba:

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

Si agrego android.jar explícitamente al classpath del proyecto de prueba, recibo excepciones como

 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) 

¿Hay una manera de hacer que el código funcione sin burlarse de todos los últimos bits de la dependencia de Android SDK? Tal vez un zombie-out android.jar ya existe?

EDIT : Por ahora terminé envolviendo clases como android.util.Log e inyectándolas en las instancias, para pruebas clásicas basadas en IOC. La sugerencia de PowerMock de Scott es mi siguiente paso cuando lo necesitaré.

EDITORIZACIÓN POSTERIOR : Robolectric !

No hay burlarse de android.jar que yo sepa. Yo uso Powermock para burlarse de todo. Una cosa que usted puede hacer para ayudar con el burlón pesado es hacer sus clases extendidas de androide como la actividad, los fragmentos, los broadcasters, el etc. fino y los tiene delegar a las clases del pojo. Usted podría tomar una decisión basada en el riesgo no a la prueba de unidad de aislamiento de las clases extendidas androide, y en su lugar la prueba de unidad de integración a través del marco de prueba de Android o algo más como Robotium.

Para pruebas de unidad de aislamiento verdadero en Android, para mí las pruebas de unidad en java jvm burlas de todas las clases de colaboración es el mejor camino a seguir.

Yo tuve el mismo problema. Quería probar POJOs sencillamente a nivel local.
Específicamente, mi código quería usar android.util.Base64.
Lo que acabé haciendo fue usar el SDK para instalar las fuentes de Android 4 y copiar la clase android.util.Base64 a mi proyecto.
Sorprendentemente, esto funcionó.

Yo tuve el mismo problema. Quería probar la lógica de negocio simple localmente. Específicamente, mi código utiliza android.util.SparseArray<E> .

He intentado 3 diferentes enfoques para que sea comprobable con junit fuera de Android.

  • En mi lógica de negocio he creado una interfaz y lo adjunto a MySparseArray<E> que hereda de SparseArray<E> . En el junit-test re-implementado la interfaz utilizando HashMap<Integer, E> . Esto funciona, pero en el largo plazo esto es mucho trabajo para hacer la lógica de negocio unit-testable si otro android.* Son necesarios.
  • Como sugirió @Tal Weiss añadí las fuentes androides de java de las clases requeridas: android.util.SparseArray.java que usa com.android.internal.util.ArrayUtils.java . Esto funciona, también, pero no me gusta añadir más fuentes de Android, sobre todo si hay mucho más dependencias
  • He descargado un stub libre binario android.jar para un viejo androide 2.2 de http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1 y lo incluyó Como lib en mi proyecto junit-java. Este frasco contiene sólo clases para namespaces android.* com.android.* , dalvik.* , dalvik.* Y framework.base.* . Esto también funciona.

En la actualidad he tenido éxito al evitar el uso de las clases de android.* Excepto SparseArray<E> en mi capa de negocio y no tiene dependencia de Contexto, Actividad o Servicio. Podría haber usado HashMap<Integer, E> en la capa de android-business en lugar de SparseArray<E> .

Unmock-plugin podría ayudar a https://github.com/bjoernQ/unmock-plugin . En mi caso funciona con SparseArray.

¿ Las pruebas empotradas de android / junit no harán lo que quieras?

  • ¿Hay una manera de ejecutar la prueba de Espresso con múltiples métodos de prueba pero sólo un método de configuración?
  • Java.lang.RuntimeException: ¡Stub! Ejecutar Junit en el proyecto de Android
  • RxJava file.createNewFile () devuelve siempre TRUE
  • Junit usando ActivityInstrumentationTestCase2 - Excepción en el constructor: Stub
  • Tratando de probar un módulo de Android en la aplicación MultiDex, com.android.test.runner.MultiDexTestRunner no se reconoce
  • Akquinet (Android con el arquetipo de prueba) - las pruebas de unidad no se ejecutan
  • Junit testing con gradle para un proyecto android
  • Necesita ayuda para escribir una prueba de unidad usando Mockito y JUnit4
  • Mocking Static Methods con PowerMockito en Android
  • Unidad de prueba Java clase que carga la biblioteca nativa
  • ¿Por qué no puedo importar AndroidJUnit4 y ActivityTestRule en mi clase de prueba de unidad?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.