2013-08-06 12 views
6

Ho un'applicazione Android che utilizza frammenti e ha implementato ActionBarCompat. Ho scritto semplice test Robolectric illustrato di seguito:Robolectric utilizzando Frammenti e ActionBarCompat NullPointerException

@Test 
public void shouldNotBeNull() throws Exception { 
    MainFragment mainFragment = new MainFragment(); 
    startFragment(mainFragment); 
    assertThat(mainFragment, notNullValue()); 
    assertThat(mainFragment.getActivity(), notNullValue()); 
} 

private void startFragment(MainFragment fragment) { 
    FragmentActivity activity = new FragmentActivity(); 
    shadowOf(activity).callOnCreate(null); 
    shadowOf(activity).callOnStart(); 
    shadowOf(activity).callOnResume(); 

    FragmentManager fragmentManager = activity.getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragmentTransaction.add(fragment, null); 
    fragmentTransaction.commit(); 
} 

sto ottenendo seguente eccezione:

java.lang.NullPointerException: null 
at android.app.Activity.invalidateOptionsMenu(Activity.java:2595) 
at android.support.v4.app.ActivityCompatHoneycomb.invalidateOptionsMenu(ActivityCompatHoneycomb.java:30) 
at android.support.v4.app.FragmentActivity.supportInvalidateOptionsMenu(FragmentActivity.java:572) 
at android.support.v4.app.Fragment.setHasOptionsMenu(Fragment.java:708) 
at com.example.android.ui.MainFragment.onCreate(MainFragment.java:599) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:834) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) 
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420) 
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:37) 
at org.robolectric.shadows.ShadowLooper.post(ShadowLooper.java:198) 
at org.robolectric.shadows.ShadowHandler.postDelayed(ShadowHandler.java:56) 
at org.robolectric.shadows.ShadowHandler.post(ShadowHandler.java:51) 
at android.os.Handler.post(Handler.java) 
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1322) 
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) 
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) 
at com.example.android.ui.MainFragmentTest.startFragment(MainFragmentTest.java:36) 
at com.example.android.ui.MainFragmentTest.shouldNotBeNull(MainFragmentTest.java:22) 

Quando si utilizza qualcosa di simile:

MainActivity activity = new MainActivity(); 
shadowOf(activity).callOnCreate(null); 
shadowOf(activity).callOnStart(); 
shadowOf(activity).callOnResume(); 

dove MainActivity è l'attività supporto per MainFragment, I ottenere la seguente eccezione:

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
at org.robolectric.res.builder.RobolectricPackageManager.getActivityInfo(RobolectricPackageManager.java:59) 
at android.support.v7.app.ActionBarActivityDelegate.getUiOptionsFromMetadata(ActionBarActivityDelegate.java:157) 
at android.support.v7.app.ActionBarActivityDelegateICS.onCreate(ActionBarActivityDelegateICS.java:53) 
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98) 
at com.example.android.ui.MainActivity.onCreate(MainActivity.java:45) 
at org.robolectric.shadows.ShadowActivity.invokeReflectively(ShadowActivity.java:176) 
at org.robolectric.shadows.ShadowActivity.callOnCreate(ShadowActivity.java:121) 
at com.example.android.ui.MainFragmentTest.startFragment(MainFragmentTest.java:28) 
at com.example.android.ui.MainFragmentTest.shouldNotBeNull(MainFragmentTest.java:22) 

Sospetto che potrebbe essere qualcosa su ActionBarCompat e Robolectric che non sono compatibili. Qualsiasi aiuto sarebbe apprezzato.

+0

Cosa significa shadowOf (attività) '' ritorno? – Terry

+0

Grazie per aver partecipato. Per quanto riguarda la spiegazione del metodo shadowOf, la migliore viene data sul sito web robolectric: "Talvolta le classi Android non forniscono metodi per accedere allo stato degli oggetti Android sotto test. I metodi Robolectric.shadowOf() forniscono un riferimento alle istanze shadow che rappresentano Oggetti Android, che consentono ai test di affermare in stato altrimenti non disponibile ". Se diversamente si presuppone che shadowOf (attività) restituisca null durante il debug, id no. –

+0

Il problema persiste ancora, quindi qualsiasi suggerimento sarebbe utile. –

risposta

0

A partire dal Robolectric 2.4, si suppone per sostenere la libreria AppCompat. Ci sono alcuni trucchi però come non funziona fuori dalla scatola. Le cose che mi hanno aiutato:

  1. Creazione di un file project.properties con il seguente contenuto

Come descritto in the config manual:

target=android-19 android.library.reference.1=/../../build/intermediates/exploded-aar/com.android.support/appcompat-v7/20.0.0  
android.library.reference.2=/../../build/intermediates/exploded-aar/com.android.support/support-v4/20.0.0 
android.library.reference.3=/../../build/intermediates/exploded-aar/com.viewpagerindicator/library/2.4.1 
  1. exculdes impostazione nel build.gradle per Robolectric

A quanto pare Robolectric ha le sue versioni delle librerie di supporto in modo che il seguito è necessario per prevenire eventuali dipendenze duplicati (riferimento da here):

androidTestCompile('org.robolectric:robolectric:2.4') { 
    exclude module: 'classworlds' 
    exclude module: 'commons-logging' 
    exclude module: 'httpclient' 
    exclude module: 'maven-artifact' 
    exclude module: 'maven-artifact-manager' 
    exclude module: 'maven-error-diagnostics' 
    exclude module: 'maven-model' 
    exclude module: 'maven-project' 
    exclude module: 'maven-settings' 
    exclude module: 'plexus-container-default' 
    exclude module: 'plexus-interpolation' 
    exclude module: 'plexus-utils' 
    exclude module: 'wagon-file' 
    exclude module: 'wagon-http-lightweight' 
    exclude module: 'wagon-provider-api' 
    exclude group: 'com.android.support', module: 'support-v4' 
    exclude group: 'com.android.support', module: 'appcompat-v7' }