Java 如何在Android单元测试中模拟Bundle方法?

Java 如何在Android单元测试中模拟Bundle方法?,java,android,unit-testing,Java,Android,Unit Testing,我有一个处理片段创建的控制器类。让我们这样说: public class FragmentController { public static Fragment newInstance(String title, int total) { return total > 0? MultipleDataFragment.newInstance(title, total) : SingleDataFragment.newInstance(titl

我有一个处理片段创建的控制器类。让我们这样说:

public class FragmentController {

    public static Fragment newInstance(String title, int total) {
        return total > 0? MultipleDataFragment.newInstance(title, total)
            : SingleDataFragment.newInstance(title);
    }
}
在我的测试(标准Junit4测试类)中,我有:

因为我没有嘲弄这个包裹,所以我很高兴

java.lang.RuntimeException: Method putString not mocked.Set
问题是如何模拟Bundle对象以便执行测试?我是否需要在创建Bundle对象的每个类中使用静态方法,或者有更好的方法来实现这一点


这方面的任何例子都值得赞赏。

一种方法是使用一个强大的模拟框架,例如,它甚至可以拦截新对象的构造

这应该对您有用,但是模拟像Bundle这样的“简单”类意味着一些工作-您也可以通过使用来使用真正的实现。

使用来取消模拟Bundle类。您需要使用Android 4.4取消模拟(unmock'org.roblectric:Android all:4.4_r1-roblectric-1'),因为Android的更高版本引用了非标准Java方法


您还需要保留ArrayMap和MapCollections。

有关Bundle类的模拟示例,您可能需要签出。关于unmack,我在使用Bundle时遇到了问题,因为在运行简化的测试用例时,
mMap
出现了
NoSuchFieldError
。从API 21开始,Bundle扩展了BaseBundle,这就是它找不到mMap的原因。不幸的是,卸载BaseBundle没有帮助,因为ArrayMap现在使用JVM不包含的System.arraycopy()的非标准版本。因此,卸载捆绑包不起作用。@ErikBrowne您的解决方案是什么?请注意,您的getInstance()方法不完整。它们甚至没有返回语句。
public class SingleDataFragment extends Fragment {
    public static SingleDataFragment newInstance( String title, int total) {
        Bundle b = new Bundle();
        b.putString("title", title);
        b.putInt("total", total);
    }
}
@Test
public void testNewInstanceCreteMultipleData() throws Exception {
    Fragment f = FragmentController.newInstance("Hello", 5);

    assertTrue("MultipleDataFragment should be created"
        , f instanceOf MultipleDataFragment);
}
java.lang.RuntimeException: Method putString not mocked.Set