2015-12-14 41 views
3

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

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

但是,一旦我融入PowerMock,投行失败,

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

我怎样才能解决这个问题?

+0

你能看到调试完整的类名吗? –

+0

是的,我可以,它是RoboApplication,配置中的类型相同。 –

回答

4

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

虽然名称相同,但Class对象实际上并不相同:Robolectric和PowerMock都通过加载通过定制类加载程序的测试来工作。这些类加载器可以更改有问题的类,从而允许您替换静态/最终Android系统类和方法[Robolectric]或所有静态/最终类[PowerMock]。这是PowerMock和Robolectric都依靠自己的JUnit4 Runner的原因之一:这样他们可以从他们自己的修改类加载器中加载相应的类。由于这个原因,即使实例名称相同,来自同一源文件的,但实例不能转换为其他类别的实例:每个框架都可以更改类实现,因此它们不是'不一定相互兼容。

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

参见:

+0

谢谢你的精彩写作! –

1

我还需要为了开始一个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的应用程序配置中使用它,但最终导致了投射问题。所以我希望这可以有任何帮助。

当然,该制定者不应该投入生产。但这是我能想出这个工作的唯一途径。