¿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?

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 
  • Cambiar automáticamente el fondo del botón y el aspecto del texto cuando se presiona (como iOS)?
  • Agregar sombra al ShapeDrawable mediante programación
  • La elevación no se muestra en la barra de herramientas de los dispositivos pre-pirulí
  • Robolectric sombra no funciona
  • Android Drop Shadow en la vista
  • Cómo configurar la sombra de una vista en Android?
  • ¿Tiene el sistema operativo Android archivos como / etc / passwd, / etc / shadow y / etc / group?
  • Android Paint setShadowLayer () ignora el color de su Paint
  • La sombra CardView no se procesa cuando se convierte en mapa de bits
  • Cómo proporcionar la sombra al botón
  • Cómo crear sombra de botón en el estilo de diseño de material android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.