如何使 ActivityUnitTestCase 中的片段的 isResumed() return 为真?
How to make isResumed() return true for a Fragment in an ActivityUnitTestCase?
我写了一个片段 class,在某个时候,在执行某事之前会仔细检查 isResumed()
。我想编写测试以确保此代码运行。但是,在我从 ActivityUnitTestCase
派生的测试用例中,isResumed()
似乎总是 return false
。在这样的测试中有什么方法可以使它 return true
吗?我正在使用支持库的片段 classes.
这是一个示例测试,它使用与我的实际测试使用的代码类似的代码,并演示了问题。 testIsResumed()
总是失败,因为 isResumed()
是假的,尽管在 activity 和片段上都调用了 onStart()
和 onResume()
,并且 [=21= 的自由使用]:
public class FragmentIsResumedTest
extends ActivityUnitTestCase<FragmentIsResumedTest.TestActivity> {
public static class TestFragment
extends android.support.v4.app.Fragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return new LinearLayout(getContext());
}
}
public static class TestActivity
extends android.support.v4.app.FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new LinearLayout(this));
}
}
public FragmentIsResumedTest() {
super(TestActivity.class);
}
public void testIsResumed() {
startActivity(
new Intent(
getInstrumentation().getTargetContext(),
TestActivity.class),
null, null);
getInstrumentation().waitForIdleSync();
TestActivity activity = getActivity();
TestFragment fragment = new TestFragment();
fragment.onCreate(null);
getInstrumentation().callActivityOnStart(activity);
activity.getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, fragment, "FragmentTag")
.commit();
getInstrumentation().callActivityOnResume(activity);
fragment.onStart();
fragment.onResume();
getInstrumentation().waitForIdleSync();
activity.getSupportFragmentManager().executePendingTransactions();
getInstrumentation().waitForIdleSync();
assertTrue(fragment.isResumed());
}
}
如何在从 ActivityUnitTestCase
扩展的单元测试中使 isResumed()
为真?
缺少的是问题中的测试设置从不调用 Activity.onPostResume()
。在Support Library的FragmentActivity
、this is where the fragments are resumed from, by calling dispatchResume()
on the FragmentManager
. Simply calling Fragment.onResume()
manually won't cause isResumed()
to return true. And for some reason, Instrumentation.callActivityOnResume()
never calls onPostResume()
中并没有对应的callActivityOnPostResume()
.
一个简单的解决方法是在 TestActivity
中制作 onPostResume()
public:
public static class TestActivity
extends android.support.v4.app.FragmentActivity {
@Override
public void onPostResume() {
super.onPostResume();
}
/* ... */
}
并在测试设置中 callActivityOnResume()
之后的某个时间调用它。这似乎处理了所有未决的片段事务,因此不再需要 executePendingTransactions()
。即使在删除了对 waitForIdleSync()
的所有调用之后,以下测试代码对我仍然有效。使用 Mockito.spy()
,我们可以看到片段上的所有生命周期方法都被调用了:
TestActivity activity = getActivity();
TestFragment fragment = spy(new TestFragment());
getInstrumentation().callActivityOnStart(activity);
activity.getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, fragment, "FragmentTag")
.commit();
getInstrumentation().callActivityOnResume(activity);
activity.onPostResume();
assertTrue(fragment.isResumed());
InOrder inOrder = inOrder(fragment);
inOrder.verify(fragment).onCreate(any(Bundle.class));
inOrder.verify(fragment).onViewCreated(any(View.class), any(Bundle.class));
inOrder.verify(fragment).onActivityCreated(any(Bundle.class));
inOrder.verify(fragment).onStart();
inOrder.verify(fragment).onResume();
我写了一个片段 class,在某个时候,在执行某事之前会仔细检查 isResumed()
。我想编写测试以确保此代码运行。但是,在我从 ActivityUnitTestCase
派生的测试用例中,isResumed()
似乎总是 return false
。在这样的测试中有什么方法可以使它 return true
吗?我正在使用支持库的片段 classes.
这是一个示例测试,它使用与我的实际测试使用的代码类似的代码,并演示了问题。 testIsResumed()
总是失败,因为 isResumed()
是假的,尽管在 activity 和片段上都调用了 onStart()
和 onResume()
,并且 [=21= 的自由使用]:
public class FragmentIsResumedTest
extends ActivityUnitTestCase<FragmentIsResumedTest.TestActivity> {
public static class TestFragment
extends android.support.v4.app.Fragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return new LinearLayout(getContext());
}
}
public static class TestActivity
extends android.support.v4.app.FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new LinearLayout(this));
}
}
public FragmentIsResumedTest() {
super(TestActivity.class);
}
public void testIsResumed() {
startActivity(
new Intent(
getInstrumentation().getTargetContext(),
TestActivity.class),
null, null);
getInstrumentation().waitForIdleSync();
TestActivity activity = getActivity();
TestFragment fragment = new TestFragment();
fragment.onCreate(null);
getInstrumentation().callActivityOnStart(activity);
activity.getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, fragment, "FragmentTag")
.commit();
getInstrumentation().callActivityOnResume(activity);
fragment.onStart();
fragment.onResume();
getInstrumentation().waitForIdleSync();
activity.getSupportFragmentManager().executePendingTransactions();
getInstrumentation().waitForIdleSync();
assertTrue(fragment.isResumed());
}
}
如何在从 ActivityUnitTestCase
扩展的单元测试中使 isResumed()
为真?
缺少的是问题中的测试设置从不调用 Activity.onPostResume()
。在Support Library的FragmentActivity
、this is where the fragments are resumed from, by calling dispatchResume()
on the FragmentManager
. Simply calling Fragment.onResume()
manually won't cause isResumed()
to return true. And for some reason, Instrumentation.callActivityOnResume()
never calls onPostResume()
中并没有对应的callActivityOnPostResume()
.
一个简单的解决方法是在 TestActivity
中制作 onPostResume()
public:
public static class TestActivity
extends android.support.v4.app.FragmentActivity {
@Override
public void onPostResume() {
super.onPostResume();
}
/* ... */
}
并在测试设置中 callActivityOnResume()
之后的某个时间调用它。这似乎处理了所有未决的片段事务,因此不再需要 executePendingTransactions()
。即使在删除了对 waitForIdleSync()
的所有调用之后,以下测试代码对我仍然有效。使用 Mockito.spy()
,我们可以看到片段上的所有生命周期方法都被调用了:
TestActivity activity = getActivity();
TestFragment fragment = spy(new TestFragment());
getInstrumentation().callActivityOnStart(activity);
activity.getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, fragment, "FragmentTag")
.commit();
getInstrumentation().callActivityOnResume(activity);
activity.onPostResume();
assertTrue(fragment.isResumed());
InOrder inOrder = inOrder(fragment);
inOrder.verify(fragment).onCreate(any(Bundle.class));
inOrder.verify(fragment).onViewCreated(any(View.class), any(Bundle.class));
inOrder.verify(fragment).onActivityCreated(any(Bundle.class));
inOrder.verify(fragment).onStart();
inOrder.verify(fragment).onResume();