2015-12-14 6 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 взаимно несовместимы из-за использования их собственных загрузчиков классов.

Несмотря на то, что имена одинаковы, объекты класса на самом деле не совпадают: Robolectric и PowerMock работают, загружая тест через пользовательские загрузчики классов . Эти загрузчики классов меняют рассматриваемые классы, позволяя вам заменить статические/окончательные системные классы и методы Android [Robolectric] или все статические/конечные классы [PowerMock]. Это связано с тем, что PowerMock и Robolectric полагаются на собственный JUnit4 Runner: таким образом, они могут загружать соответствующие классы из своих собственных модификаторов классов.

Из-за этого экземпляры не могут быть переведены в классы друг друга, хотя они имеют одинаковое имя и имеют значение из того же исходного файла: каждая среда может изменять реализацию класса, t обязательно совместимы друг с другом.

Вам необходимо выбрать один фреймворк или другое: используйте 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);

FYI, я попытался не издеваться над классом приложения и использовал ((App)RuntimeEnvironment.application), но это не сработало. Я также попытался подклассифицировать его и использовать его в конфигурации приложения Robolectric, но в итоге появился вопрос о кастинге. Поэтому я надеюсь, что это может помочь.

Конечно, этот сеттер не должен вступать в серийное производство. Но это единственный способ понять, как это работает.

 Смежные вопросы

  • Нет связанных вопросов^_^