片段getActivity()在Activity JUnit测试中返回null

时间:2013-01-11 17:35:01

标签: android unit-testing junit android-fragments

我为Activity编写了Android JUnit测试实例化片段(实际上是制表符)。在测试期间,当我尝试对这些选项卡执行任何操作时,它们会崩溃,因为其中的getActivity()方法返回null。实际应用程序(不是测试)从不显示此行为,并且片段getActivity()始终在那里返回正确的父活动。我的测试用例如下:

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

AllTabs以这种方式创建一个片段,然后是必需的:

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

这里,所有片段最初都是占位符,后来被实际片段替换:

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

logcat显示新片段已实例化。在相同的布局中,还有前面提到的AllTabs片段似乎没有这个问题(否则它将如何以及如何获得FragmentManager):

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

最令人印象深刻的是,当我直接在正确活动上获得的片段管理器上调用attach时,这仍然没有效果。我试着延迟5秒钟(我已经读过transaction may be delayed),我试图通过runOnUiThread调用剩下的测试 - 没有任何帮助。

问题需要这样做才能在测试期间将我的片段附加到活动中。我有片段,我有活动,我不能把它们连在一起。

1 个答案:

答案 0 :(得分:9)

即使您在事务上调用.commit(),它仍然没有完成,片段只是懒惰地附加。

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

这最终将所有片段附加到活动中。在运行应用程序本身时似乎是多余的,但在JUnit测试用例中是必需的。