¿Cómo puedo sombrear el PackageManager con Robolectric
Mi aplicación de Android tiene un método simple para despedir una intención de mostrar una URL.
protected void launchBrowser(int id) { Uri uri = Uri.parse( getString( id ) ); Intent intent = new Intent( ACTION_VIEW, uri); PackageManager packageManager = getPackageManager(); List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); if (activities.size() > 0) { startActivity(intent); } else { Toast.makeText(getApplicationContext(), "ERROR - no application to display a web page", Toast.LENGTH_SHORT).show(); } }
Estoy usando Robolectric para la prueba de unidad, pero estoy teniendo problemas para verificar este método. Específicamente, getPackageManager()
siempre devuelve null. ¿Cómo puedo sombrear el PackageManager
? Intenté crear un ShadowPackageManager
y llamar a bindShadowClass
, pero ninguno de mi código se ejecuta – getPackageManager()
devuelve siempre null
. También intenté StubPackageManager
el contexto de la aplicación y devolver un concreto StubPackageManager
, pero obtuvo los mismos resultados. Tal vez he estado buscando / mirando demasiado tiempo – ¿hay una mejor manera de unidad de prueba de este método?
- Cómo deshabilitar la sombra azul en el desplazamiento (aplicaciones de Android).
- Cambio de Android Color de sombra de elevación de material
- Cómo aplicar sombra a ImageView?
- Cómo colocar el lienzo en View.DragShadowBuilder.onProvideShadowMetrics
- Android "elevación" que no muestra una sombra
- Androide diseño biblioteca barra de herramientas sombra
- Cambiar la forma o la sombra del icono o eliminarlo por completo
- Google map android api v2 marcador sombras
- Android cómo dibujar un rect rectangular y sombra Layout
- ¿Cómo evitar que drawBitmap de Android sólo dibuje imágenes en negro?
- Android Eliminar sombra en el cajón de navegación
- Cómo eliminar la sombra circundante FloatingActionButton?
- Android No se puede eliminar el color en la parte superior e inferior
Estoy usando Robolectric 2.3 para esto. Como se indica en otras respuestas, getPackageManager()
no devuelve null, pero shadowApplication.setPackageManager
ya no existe.
Puesto que no se puede burlar de PackageManager
, no puede darle una lista de Intents
para resolver. Afortunadamente, la subclase PackageManager
RobolectricPackageManager
, RobolectricPackageManager
, puede permitirle agregar estas intenciones sin un simulacro:
RobolectricPackageManager rpm = (RobolectricPackageManager)Robolectric.application.getPackageManager(); rpm.addResolveInfoForIntent(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS), new ResolveInfo());
Por alguna razón, necesitas configurar el shadow packagemanager manualmente en tu aplicación. Cree un corredor de prueba personalizado (extendiendo RobolectricTestRunner) y anule el método setApplicationState:
public class MyTestRunner extends RobolectricTestRunner { @Override public void setupApplicationstate(RobolectricConfig robolectricConfig) { super.setupApplicationState(robolectricConfig); ShadowApplication shadowApplication = shadowOf(Robolectric.application); shadowApplication.setPackageName(robolectricConfig.getPackageName()); shadowApplication.setPackageManager(new RobolectricPackageManager(Robolectric.application, robolectricConfig)); } }
A continuación, especifique en sus pruebas que desea utilizar su propio corredor de pruebas:
@RunWith(MyTestRunner.class) public class MyTest { ... }
He actualizado a la última versión de Robolectric (versión 2.1.1) y el PackageManager ya no aparece.
El código siguiente verifica que se desencadena una intención del navegador (y se configura con una url). No he probado esto en 1.x, pero pienso que trabaja allí también:
@Test public void recipeTitleShouldOpenBrowserOnClick() throws Exception { title.performClick(); ShadowActivity shadowActivity = shadowOf( detailFragment.getActivity() ); ShadowActivity.IntentForResult intent = shadowActivity.peekNextStartedActivityForResult(); // or // ShadowActivity.IntentForResult intent = shadowActivity.getNextStartedActivityForResult(); assertThat( intent.intent, equalTo( createBrowserIntentWithURL( "url" ) ) ); }
Nota : Estoy invocando la actividad de inicio de un fragmento aquí.
Simplemente añada la respuesta de aleph_null , puede usar ShadowResolveInfo.newResolveInfo()
para crear rápidamente un simulador ResolveInfo
listo para ser usado (estoy usando Robolectric 2.4).
RobolectricPackageManager rpm = (RobolectricPackageManager)Robolectric.application.getPackageManager(); rpm.addResolveInfoForIntent(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS), ShadowResolveInfo.newResolveInfo(...));
Puede configurar el ShadowPackageManager en un método separado (sin extender RobolectricTestRunner)
private void setupPackageManager() { ShadowApplication shadowApplication = shadowOf(Robolectric.application); shadowApplication.setPackageManager(mockPackageManager); List<ResolveInfo> activities = new ArrayList<ResolveInfo>(); activities.add(resolveInfo("com.test.package.Class1")); activities.add(resolveInfo("com.test.package.Class2")); when(mockPackageManager.queryIntentActivities(any(Intent.class), anyInt())).thenReturn(activities); }
Nota : Aquí, he utilizado mockito & burlado el packagemanager para mi unittest en lugar de usar el PackageManager real.
Para Robolectric 3.1 se puede
RobolectricPackageManager packageManager = RuntimeEnvironment.getRobolectricPackageManager(); // add necessary logic here
- Spinner no puede cargar una matriz de números enteros?
- Crear una instancia de una clase abstracta en Kotlin