2013-01-11 12 views
5

Ho scritto il test Android JUnit per Attività che crea istanze di frammenti (in realtà schede). Durante il test, quando provo a fare qualcosa con queste schede, si bloccano perché il metodo getActivity() in esse restituisce null. L'applicazione effettiva (non un test) non mostra mai questo comportamento e il frammento getActivity() restituisce sempre l'attività genitore giusta lì. Il mio banco di prova assomiglia:Il frammento getActivity() restituisce null in Activity JUnit test

public class SetupPanelTest extends ActivityUnitTestCase<MyAct> { 

    FSetup s; 

    public SetupPanelTest() { 
    super(MyAct.class); 
    } 

    protected void setUp() throws Exception { 
     super.setUp(); 
     startActivity(new Intent(), null, null); 
     final MyAct act = getActivity(); 

     AllTabs tabs = act.getTabs(); 
     String tabname = act.getResources().getString(R.string.configuration); 

     // This method instantiates the activity as said below 
     s = (FSetup) tabs.showTab(tabname); 
     FragmentManager m = act.getFragmentManager(); 
     // m.beginTransaction().attach(s).commit(); 
     //  ... and even this does not help when commented out 

     assertTrue(s instanceof FSetup); // Ok  
     assertEquals(act, s.getActivity()); // Failure 
    } 

    public void testOnPause() { 
     // this crashes because s.getActivity == null; 
     s.onPause(); 
     } 
} 

Le AllTabs crea un frammento, poi necessario, in questo modo:

FragmentManager manager = getFragmentManager(); 
Fragment fragment = manager.findFragmentByTag(tabname); 
if (fragment == null || fragment.getActivity() == null) { 
     Log.v(TAG, "Instantiating "); 
     fragment = new MyFragment(); 
     manager.beginTransaction().replace(R.id.setup_tab, fragment, tabname).commit(); 
.... 

Qui, tutti i frammenti sono inizialmente segnaposti che vengono poi sostituiti da frammenti effettivi:

<FrameLayout 
    android:id="@+id/setup_tab" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" />  

Il logcat mostra che il nuovo frammento è stato istanziato. Nello stesso layout, v'è anche il frammento già citato AllTabs che non sembra avere questo problema (dove e come si arriva FragmentManager altrimenti):

<TabWidget 
    android:id="@android:id/alltabs" 
... 

La maggior parte impressionante, quando chiamo allego direttamente sul gestore frammento ottenuto su l'attività giusta, questo non ha ancora effetto. Ho provato a mettere un ritardo di cinque secondi (ho letto che transaction may be delayed), ho provato a chiamare il resto del test attraverso runOnUiThread - nulla aiuta.

La domanda è che è necessario farlo per collegare i miei frammenti all'attività anche durante il test. Ho un frammento e ho un'attività, non posso attaccare l'uno all'altro.

risposta

9

Anche se si chiama .commit() sulla transazione, non è ancora fatto, i frammenti vengono allegati solo pigramente.

FragmentManager m = activity.getFragmentManager(); 
    m.executePendingTransactions(); 

Questo collega infine tutti i frammenti all'attività. Sembra ridondante quando si esegue l'applicazione stessa ma è richiesta nel caso di test JUnit.

Problemi correlati