使用 Robolectric 构建片段时无法找到资源 ID
Unable to find resource ID when building fragment with Robolectric
使用 Robolectric 3.3.2 我正在尝试构建一个片段并将其附加到 activity。我试过 Robolectric.buildFragment(MyFragment.class, MyActivity.class).create()
但出现异常 android.content.res.Resources$NotFoundException: Unable to find resource ID #0x1 in packages [android, com.my.package.for.android]
.
我也试过分别构建 activity 和片段并使用片段管理器附加片段,但似乎片段自动附加到虚拟 activity 所以我无法将它附加到我的activity.
简约示例:
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Build.VERSION_CODES.KITKAT, manifest = "./src/main/AndroidManifest.xml")
public class MyTest {
@Test
public void WorkingTest1() throws Exception {
Robolectric.buildFragment(MyFragment.class).create();
}
@Test
public void WorkingTest2() throws Exception {
Robolectric.buildActivity(MyActivity.class).create();
}
@Test
public void FailingTest() throws Exception {
Robolectric.buildFragment(MyFragment.class, MyActivity.class).create();
}
public static class MyActivity extends Activity {
}
public static class MyFragment extends Fragment {
}
}
经过进一步调查,我确实找到了解决方法(尽管很丑陋)。似乎 Robolectric 需要在 activity 视图层次结构中使用 id 1 的 ViewGroup。我找到的解决方案是在 activity 的 onCreate(Bundle)
中写入 findViewById(android.R.id.content).setId(1);
(或添加一个新的 ViewGroup 并以编程方式将其 id 设置为 1)。这在生产代码中似乎是一件可怕的事情,所以我制作了一个测试子类。
public class MyTestableActivity extends MyActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
findViewById(android.R.id.content).setId(1);
}
}
我已经为我的 Activity 定义了一个根 Activity 框架,因此我可以为 Robolectric 的 FragmentController 中的 FragmentManager 事务提供它:
Robolectric
.buildFragment(MyFragment.class, MyActivity.class)
.create(R.id.my_activity_frame);
在我的 Activity:
setContentView(R.id.my_activity_frame);
如果您是 运行 默认 RobolectricTestRunner ,请确保您的 res/ 文件夹与 AndroidManifest.xml 位于同一位置。
我用
之类的东西解决了问题
@RunWith(RobolectricTestRunner.class)
@Config(manifest = "./path/AndroidManifest.xml")
public class FragmentTest{
}
我通过改变其他答案解决了这个问题:
Robolectric
.buildFragment(YourFragment.class, Activity.class)
.create(android.R.id.content, new Bundle());
请注意,您也可以将 Activity.class 替换为仅静态内部测试 YourTestActivity.class。
使用 Robolectric 3.3.2 我正在尝试构建一个片段并将其附加到 activity。我试过 Robolectric.buildFragment(MyFragment.class, MyActivity.class).create()
但出现异常 android.content.res.Resources$NotFoundException: Unable to find resource ID #0x1 in packages [android, com.my.package.for.android]
.
我也试过分别构建 activity 和片段并使用片段管理器附加片段,但似乎片段自动附加到虚拟 activity 所以我无法将它附加到我的activity.
简约示例:
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Build.VERSION_CODES.KITKAT, manifest = "./src/main/AndroidManifest.xml")
public class MyTest {
@Test
public void WorkingTest1() throws Exception {
Robolectric.buildFragment(MyFragment.class).create();
}
@Test
public void WorkingTest2() throws Exception {
Robolectric.buildActivity(MyActivity.class).create();
}
@Test
public void FailingTest() throws Exception {
Robolectric.buildFragment(MyFragment.class, MyActivity.class).create();
}
public static class MyActivity extends Activity {
}
public static class MyFragment extends Fragment {
}
}
经过进一步调查,我确实找到了解决方法(尽管很丑陋)。似乎 Robolectric 需要在 activity 视图层次结构中使用 id 1 的 ViewGroup。我找到的解决方案是在 activity 的 onCreate(Bundle)
中写入 findViewById(android.R.id.content).setId(1);
(或添加一个新的 ViewGroup 并以编程方式将其 id 设置为 1)。这在生产代码中似乎是一件可怕的事情,所以我制作了一个测试子类。
public class MyTestableActivity extends MyActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
findViewById(android.R.id.content).setId(1);
}
}
我已经为我的 Activity 定义了一个根 Activity 框架,因此我可以为 Robolectric 的 FragmentController 中的 FragmentManager 事务提供它:
Robolectric
.buildFragment(MyFragment.class, MyActivity.class)
.create(R.id.my_activity_frame);
在我的 Activity:
setContentView(R.id.my_activity_frame);
如果您是 运行 默认 RobolectricTestRunner ,请确保您的 res/ 文件夹与 AndroidManifest.xml 位于同一位置。 我用
之类的东西解决了问题@RunWith(RobolectricTestRunner.class)
@Config(manifest = "./path/AndroidManifest.xml")
public class FragmentTest{
}
我通过改变其他答案解决了这个问题:
Robolectric
.buildFragment(YourFragment.class, Activity.class)
.create(android.R.id.content, new Bundle());
请注意,您也可以将 Activity.class 替换为仅静态内部测试 YourTestActivity.class。