使用 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。