2011-04-06 13 views
16

Actualmente estoy escribiendo algunas pruebas de unidades de Android, y aunque he conseguido que la mayoría de las cosas funcionen como quiero, una cosa me ha dejado algo perplejo.Obtener el resultado de una actividad después de finalizar(); en una prueba de unidad de Android

tengo el siguiente código en mi actividad bajo prueba:

Intent result = new Intent(); 
result.putExtra("test", testinput.getText().toString()); 
setResult(Activity.RESULT_OK, result); 
finish(); 

Estoy tratando de encontrar la manera de utilizar Instrumentación (o lo que sea) para ser capaz de leer el resultado de la actividad, o conseguir en el intento después de que la actividad haya terminado. ¿Alguien puede ayudar?

+0

http://stackoverflow.com/questions/4160755/testing-that-an-activity-called-setresult –

+1

Sí, pregunta similar . Lo vi antes de preguntar, pero no hubo una buena respuesta. Comenzó uno nuevo con un código ... – uvesten

+0

Dado que no puede cambiar la implementación de 'setResult (int)' y por lo tanto debe confiar en que funciona, ¿no sería suficiente simplemente verificar que el método fue llamado en su ¿Actividad actual? ' –

Respuesta

20

Puede usar la reflexión y obtener los valores directamente de la Actividad.

protected Intent assertFinishCalledWithResult(int resultCode) { 
    assertThat(isFinishCalled(), is(true)); 
    try { 
    Field f = Activity.class.getDeclaredField("mResultCode"); 
    f.setAccessible(true); 
    int actualResultCode = (Integer)f.get(getActivity()); 
    assertThat(actualResultCode, is(resultCode)); 
    f = Activity.class.getDeclaredField("mResultData"); 
    f.setAccessible(true); 
    return (Intent)f.get(getActivity()); 
    } catch (NoSuchFieldException e) { 
    throw new RuntimeException("Looks like the Android Activity class has changed it's private fields for mResultCode or mResultData. Time to update the reflection code.", e); 
    } catch (Exception e) { 
    throw new RuntimeException(e); 
    } 
} 
+0

¡Genial! Estoy usando esto en lugar de getActivity.getResultCode() dentro de una prueba unitaria, y esto funciona perfecto – coredump

-1

No estoy seguro de si es diferente para las pruebas unitarias, pero debería poder utilizar en ActividadResultado como se ve aquí: StartingActivities. Que acaba de empezar la actividad con startActivityForResult (intención, requestCode) y luego usar

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) 

de vuelta en la actividad que utiliza startActivityForResult.

+0

Sí, eso es cierto, y gracias. Sin embargo, estoy preguntando específicamente sobre el caso de prueba unitaria. – uvesten

+0

¿Puede agregar un poco más de detalle a la pregunta sobre el problema específico que está viendo? –

1

Puede hacerlo escribiendo una actividad especial cuyo único propósito es comenzar la actividad que está probando para el resultado y guardar el resultado para que confirme la corrección.

Por ejemplo, puede crear una actividad llamada ResultReceiverActivity. Proporcione tres métodos: getResultCode, getResultData y getReceivedRequestCode, que se pueden usar para verificar que la actividad evaluada arrojó los valores correctos. Creará un caso de prueba que se extiende a ActivityInstrumentationTestCase2 y el parámetro genérico sería ResultReceiverActivity. Si llama al getActivity obtendrá la instancia de la actividad.

public class ReturnedResultTest 
    extends ActivityInstrumentationTestCase2<ResultReceiverActivity> { 

    public void testReturnedResult() { 
     ResultReceiverActivity a = getActivity(); 
     assertEquals(Activity.RESULT_OK, a.getResultCode()); 
     assertEquals("myResult", a.getResultData().getStringExtra("test")); 
     assertEquals(0x9999, a.getReceivedRequestCode()); 
    } 
} 

ResultReceiverActivity tiene que anular onActivityResult, por supuesto, y sólo debe almacenar los valores de ese parámetro métodos en sus campos, así:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    this.receivedRequestCode = requestCode; 
    this.resultCode = resultCode; 
    this.resultData = data; 
} 

Por supuesto, es posible que desee personalizar la actividad que ResultReceiverActivity se inicia, y puede hacerlo fácilmente usando getIntent en su método onCreate. En su caso de prueba, llame a setActivityIntent antes de llamar a getActivity para establecer qué intención se utiliza para iniciar la actividad.

+0

¡Gracias, probaré esto! Sin embargo, me he dado cuenta de que mi pregunta debería haber sido la siguiente: pruebas unitarias del resultado de una actividad que requiere la intervención del usuario. (Es decir, la actividad toma la información de la pantalla). Fácil de probar por sí mismo, podría ser más difícil realizar una prueba unitaria. No sé si todo eso podría llamarse una "prueba de unidad", realmente ... – uvesten

7

O también se podría utilizar Robolectric y la sombra de la actividad que se está probando. Entonces, ShadowActivity le proporciona métodos para saber fácilmente si una actividad está finalizando y para recuperar su código de resultado.

A modo de ejemplo, una de mis pruebas se parece a esto:

@Test 
public void testPressingFinishButtonFinishesActivity() { 
    mActivity.onCreate(null); 
    ShadowActivity shadowActivity = Robolectric.shadowOf(mActivity); 

    Button finishButton = (Button) mActivity.findViewById(R.id.finish_button); 
    finishButton.performClick(); 

    assertEquals(DummyActivity.RESULT_CUSTOM, shadowActivity.getResultCode()); 
    assertTrue(shadowActivity.isFinishing()); 
} 
Cuestiones relacionadas