Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment getActivity() returns null in Activity JUnit test

I wrote Android JUnit test for Activity that instantiates fragments (actually tabs). During the test, when I try to do anything with these tabs, they crash because getActivity() method in them returns null. The actual application (not a test) never shows this behavior and fragment getActivity() always returns the right parent activity there. My test case looks like:

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();
        }
 }

The AllTabs creates a fragment, then required, in this way:

 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();
 ....

Here, all fragments are initially placeholders that are later replaced by the actual fragments:

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

The logcat shows that the new fragment has been instantiated. In the same layout, there is also the previously mentioned AllTabs fragment that seems not having this problem (where and how it gets FragmentManager otherwise):

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

Most impressively, when I call attach directly on the fragment manager obtained on the right activity, this still has no effect. I tried to put five seconds delay (I have read that transaction may be delayed), I tried to call the rest of the test through runOnUiThread - nothing helps.

The question is that is need to do so to attach my fragments to the activity also during the test. I have fragment and I have activity, I cannot attach one to another.

like image 648
Audrius Meškauskas Avatar asked Jan 11 '13 17:01

Audrius Meškauskas


1 Answers

Even if you call .commit() on transaction, it is still not done, fragments are attached only lazily.

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

This finally attaches all fragments to the activity. Seems redundant when running the application itself but required in JUnit test case.

like image 185
Audrius Meškauskas Avatar answered Oct 04 '22 04:10

Audrius Meškauskas