你如何投射RuntimeEnvironment.application?

时间:2015-12-14 23:38:22

标签: android mockito robolectric powermock powermockito

运行Robolectric测试时,RuntimeEnvironment.application的类型由您的配置决定。假设我将RoboApplication.class配置为我的测试应用程序,我可以将RuntimeEnvironment.application强制转换为我的类型。

RoboApplication app = (RoboApplication) RuntimeEnvironment.application;
app.doSomething();

但是,一旦我整合了PowerMock,投射线就会失败

java.lang.ClassCastException: RoboApplication cannot be cast to RoboApplication

如何解决此问题?

2 个答案:

答案 0 :(得分:4)

这是一个问题,因为 PowerMock和Robolectric由于使用了自己的类加载器而互不兼容

即使名称相同,Class对象实际上也不相同:Robolectric和PowerMock都通过自定义类加载器加载测试来工作。这些类加载器更改了有问题的类,允许您替换静态/最终的Android系统类和方法[Robolectric]或所有静态/最终类[PowerMock]。这是PowerMock和Robolectric都依赖于拥有自己的JUnit4 Runner的部分原因:这样他们就可以从他们自己的修改类加载器加载适当的类。

因此,实例不能转换为其他类,即使它们具有相同的名称并且来自同一源文件的发起:每个框架都可以更改类的实现,所以他们不一定彼此兼容。

您需要选择一个框架或另一个框架:使用Robolectric shadows,可能直接使用EasyMock或Mockito,或使用PowerMock手动存根Android基础架构调用。

另见:

答案 1 :(得分:1)

我还需要一个app引用来启动Dagger2模块。经过几次尝试并获得相同的强制转换异常错误后,我得到了我的应用程序,如下所示

public class App extends Application {

private static AppComponent appComponent;

@Override
public void onCreate() {
    super.onCreate();

    if( appComponent==null ){

        appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
    }
}

public static AppComponent getAppComponent() {
    return appComponent;
}

public static void setAppComponent(AppComponent component){
    appComponent = component;
}

}

在我的Robolectric / PowerMock测试仪中:

@Before
public void before() throws Exception {

    App appMocked = PowerMockito.mock(App.class);
    App.setAppComponent(DaggerAppComponent.builder().appModule(new AppModule(appMocked)).build());
    ....
}

然后,我的活动只需调用App.getAppComponent().inject(this);

仅供参考,我试图不嘲笑应用类并使用((App)RuntimeEnvironment.application),但这并不起作用。我也尝试将其子类化,并在Robolectric的应用程序配置中使用它,但结果是铸造问题。所以我希望这可以有所帮助。

当然,那个制定者不应该投入生产。但这是我能想到的唯一方法。