8

No he encontrado ningún ejemplo sobre cómo hacer esto. Estoy asumiendo que no es posible sobre la base de ejemplos como este:¿Es posible inyectar simulaciones con fines de prueba con AndroidAnnotations?

@Bean(MyImplementation.class) 
MyInterface myInterface; 

donde ya se determina la clase de inyectar.

+0

¿Está buscando probar su clase o la clase generada por AndroidAnnotations? –

+0

Quiero probar una clase que escribo. Quiero inyectar simulacros en la clase que escribo para el código de prueba e inyectar objetos "reales" para la producción. – apollodude217

Respuesta

6

La pregunta es, ¿son pruebas unitarias o pruebas de integración?

Si está realizando pruebas unitarias, le sugiero que use burlas a la manera antigua, utilizando un setter e intentando probar el código Java sin el marco de inyección de dependencia involucrado. Esto pondrá a prueba tu clase de forma aislada y evita una gran complejidad.

lo que quiero decir:

public class Test{ 

    ClassInTest inTest; 
    MyInterface myInterface; 

    @Before 
    public void setup(){ 
     inTest = new ClassInTest(); 
     //or your favorite mocking frameowrk 
     myInterface = EasyMock.createMock(MyInterface.class); 
     inTest.setMyInterface(myInterface); 
    } 

    @Test 
    public void testMethod(){ 
     //...mocking test code 
    } 
} 

Por supuesto, las pruebas de Actividades Android (y otras extensiones de Android) es difícil a causa de la excepción tirar talones y clases/métodos finales. Aquí es donde Robolectric es útil (y muy recomendable) para instanciar/sombrear la API de Android.

Si está realizando pruebas de integración, es posible que desee tomar otro enfoque. Personalmente, trataría de no burlarme durante las pruebas de integración mientras trato de probar la aplicación como se ejecutaría en producción. Pero, si realmente quieres burlarte, podrías usar un enfoque similar para las pruebas unitarias e introducir un simulacro después de levantar la clase de actividad generada. Cabe destacar que puede realizar pruebas de integración directamente en el hardware utilizando marcos como Robotium.

Más a su pregunta, no conozco ninguna instalación de AndroidAnnotaciones específicamente para inyectar Mocks o introducir Mocks en el árbol de dependencias inyectado de una aplicación.

+0

Gracias. Empecé a usar Robolectric para pruebas unitarias. En el ejemplo que dices arriba, ¿estás diciendo que llames al constructor de mi clase en el método de prueba para pasar por alto las anotaciones de Android durante las pruebas? – apollodude217

+1

Llamar al constructor (con la implicación de Robolectic) solo le proporciona una instancia de la actividad. No diría que esto pasa por alto las anotaciones de Android. Pero, si prueba su clase "MyActivity" (frente a "MyActivity_"), entonces no tendrá el código generado responsable de DI desde AA. –

8

Un complemento a johncarl respuesta:

  • No hay manera de saber AndroidAnnotations que desea inyectar burla en lugar de los objetos reales, ya que funciona en tiempo de compilación, por lo que el código debe ser siempre la producción Listo.

  • Recomendaría probar las actividades generadas, en complemento con Robolectric. Las anotaciones están agregando comportamiento a su código, por lo que no debe probarlo como si no hubiera anotaciones.

  • Tenga cuidado al probar el comportamiento de sus actividades, no el comportamiento de AndroidAnnotaciones. El framework ya tiene pruebas propias para verificar que las anotaciones funcionen correctamente :).

  • Puede dejar que AndroidAnnciones DI suceda, y luego reinyectar la dependencia burlada. Los campos tienen al menos alcance predeterminado, lo que significa que se puede acceder desde el mismo paquete, por lo que deberá crear la prueba en el mismo paquete que la actividad.

    MyActivity_ activity = new MyActivity_(); 
    
    // myInterface gets injected 
    activity.onCreate(null); 
    
    // you reinject myInterface 
    activity.myInterface = Mockito.mock(MyInterface.class); 
    
  • En AndroidAnnotations, dependencias se inyectan llamando MyImplementation_.getInstance_(). Puede usar la manipulación del código de bytes en tiempo de ejecución con una herramienta como PowerMock para permitir que el método getInstance_() de MyImplementation_ devuelva un simulacro. Sin embargo, esto podría requerir un poco de trabajo inicial, porque tendrías que mezclar el corredor de prueba PowerMock y el corredor de prueba Robolectric.

Editar: He actualizado el documentation con contenido basado en esta cuestión.

+1

+1. Es interesante que sugiera probar las Actividades generadas (pt.2). Supongo que hay suficientes cambios en la Actividad para justificar este enfoque. –

+0

Ese es exactamente mi punto :) –

+1

@ Piwaï No estoy seguro de cómo funcionará el enfoque de burla anterior. Si tiene algún método anotado con AfterViews, se ejecutará como parte de la creación de la actividad. Si estos métodos tienen alguna dependencia, fallarán, ya que aún no has tenido la oportunidad de burlarlos. ¿Alguna idea sobre cómo solucionar esto? – Neil

Cuestiones relacionadas