¿Cómo puedo probar una Intención lanzada / enviada desde una Actividad?

¿Cómo puedo crear un caso de prueba de Android JUnit que pruebe el contenido de un intento generado dentro de una actividad?

Tengo una actividad que contiene una ventana de EditText, y cuando el usuario ha terminado de introducir los datos requeridos, la actividad lanza una intención a un IntentService que registra los datos y continúa con el proceso de la aplicación. Aquí es la clase que quiero probar, el OnEditorActionListener / PasscodeEditorListener se crea como una clase separada:

public class PasscodeActivity extends BaseActivity { EditText m_textEntry = null; PasscodeEditorListener m_passcodeEditorListener = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.passcode_activity); m_passcodeEditorListener = new PasscodeEditorListener(); m_textEntry = (EditText) findViewById(R.id.passcode_activity_edit_text); m_textEntry.setTag(this); m_textEntry.setOnEditorActionListener(m_passcodeEditorListener); } @Override protected void onPause() { super.onPause(); /* * If we're covered for any reason during the passcode entry, * exit the activity AND the application... */ Intent finishApp = new Intent(this, CoreService.class); finishApp.setAction(AppConstants.INTENT_ACTION_ACTIVITY_REQUESTS_SERVICE_STOP); startService(finishApp); finish(); } } class PasscodeEditorListener implements OnEditorActionListener{ @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { PasscodeActivity activity = (PasscodeActivity) v.getTag(); boolean imeSaysGo = ((actionId & EditorInfo.IME_ACTION_DONE)!=0)?true:false; boolean keycodeSaysGo = ((null != event) && (KeyEvent.ACTION_DOWN == event.getAction()) && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER))?true:false; if (imeSaysGo || keycodeSaysGo){ CharSequence seq = v.getText(); Intent guidEntry = new Intent(activity, CoreService.class); guidEntry.setAction(AppConstants.INTENT_ACTION_PASSCODE_INPUT); guidEntry.putExtra(AppConstants.EXTRA_KEY_GUID, seq.toString()); activity.startService(guidEntry); return true; } return false; } } 

¿Cómo puedo interceptar los dos posibles intentos de salida generados por la actividad y verificar su contenido?

Gracias

Pensé en cómo utilizar ContextWrapper con la ayuda de otro sitio web.

Utilice ContextWrapper y anule todas las funciones de intención. Generalizando para todas mis pruebas de actividad, extendí la clase ActivityUnitTestCase e implementé la solución como un shim. Disfrutar:

 import android.app.Activity; import android.app.Instrumentation; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.test.ActivityUnitTestCase; public class IntentCatchingActivityUnitTestCase<T extends Activity> extends ActivityUnitTestCase<T> { protected Activity m_activity; protected Instrumentation m_inst; protected Intent[] m_caughtIntents; protected IntentCatchingContext m_contextWrapper; protected class IntentCatchingContext extends ContextWrapper { public IntentCatchingContext(Context base) { super(base); } @Override public ComponentName startService(Intent service) { m_caughtIntents = new Intent[] { service }; return service.getComponent(); } @Override public void startActivities(Intent[] intents) { m_caughtIntents = intents; super.startActivities(intents); } @Override public void startActivity(Intent intent) { m_caughtIntents = new Intent[] { intent }; super.startActivity(intent); } @Override public boolean stopService(Intent intent) { m_caughtIntents = new Intent[] { intent }; return super.stopService(intent); } } // --// public IntentCatchingActivityUnitTestCase(Class<T> activityClass) { super(activityClass); } protected void setUp() throws Exception { super.setUp(); m_contextWrapper = new IntentCatchingContext(getInstrumentation().getTargetContext()); setActivityContext(m_contextWrapper); startActivity(new Intent(), null, null); m_inst = getInstrumentation(); m_activity = getActivity(); } protected void tearDown() throws Exception { super.tearDown(); } } 

Alternativamente, usted podría volver a factorizar su código para hacer "limpio" unidad de prueba (me refiero a una prueba de unidad que tiene todo burlado excepto la clase bajo prueba). En realidad, tengo una situación yo mismo, donde recibo una java.lang.RuntimeException: Stub! Porque el código que quiero probar la unidad crea nuevos Intentes que contienen simulacros que he inyectado.

Considero la creación de mi propia fábrica para intentos. Entonces podría inyectar una fábrica despreciada a mi clase bajo prueba:

 public class MyClassToBeTested { public MyClassToBeTested(IntentFactory intentFactory) { //assign intentFactory to field } .... public void myMethodToTestUsingIntents() { Intent i = intentFactory.create(); i.setAction(AppConstants.INTENT_ACTION_PASSCODE_INPUT); //when doing unit test, inject a mocked version of the //IntentFactory and do the necessary verification afterwards. .... } } 

Mi situación no es la misma que la tuya, pero creo que podrías aplicar un patrón de fábrica para resolverlo también. Yo prefiero escribir código para soportar verdaderas pruebas de unidad, pero debo admitir que su solución es bastante inteligente.

  • Prueba de Android: TestCase se ejecuta pero ActivityInstrumentationTestCase2 no
  • Marco de prueba de gradle de Android: una sola clase
  • Cómo escribir prueba funcional automatizada con Facebook SDK en la aplicación de Android?
  • No se puede iniciar el servicio no enlazado dentro de Android JUnit 4 instrumentado prueba
  • Android Espresso: ViewPager no tiene instancia de adaptador
  • Prueba de Google Play Alpha y Beta con diferentes puntos finales o parámetros personalizados
  • Cómo utilizar Espresso Idling Resource
  • Pasando Variables a través de la línea de comandos con Spoon / Espresso (android-test-kit)
  • Clases de utilidad comunes para proyectos de prueba de Android
  • La ejecución de instrumentación falló debido a 'java.lang.IllegalAccessError'. Gradle + Espresso
  • Prueba instrumental de una vista en MVP
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.