2015-12-14 40 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的應用程序配置中使用它,但最終導致了投射問題。所以我希望這可以有任何幫助。

當然,該制定者不應該投入生產。但這是我能想出這個工作的唯一途徑。