AssertionFailedError в ApplicationTestCase.createApplication () в новых версиях Android при использовании MockContext

Я пишу приложение Android ApplicationTestCase (пример TemperatureConverterApplicationTests, найденный в Руководстве по тестированию приложений Android Диего Т. Милано на стр. 171). Пример был написан для Android 2.3, и он, похоже, не работает для Android 4. Вам не обязательно знать книгу, чтобы понять проблему, поскольку я упростил ее.

Это отлично работает с Android 2.3.3 (API 10):

setContext(new MockContext()); createApplication(); 

[Точнее, UnsupportedOperationException выбрано потому, что getPackageName () не реализовано. Но это нормально и может быть решена с помощью подкласса MockContext (), который реализует getPackageName () и getSharedPreferences (). Это не актуально, потому что проблема все еще существует даже после этого.]

Проблема в том, что с Android 4.1.2 (API 16) это не работает. Я получаю AssertionFailedError, который через некоторую отладку обнаружил, что из-за исключения ClassCastException в строке 100 ApplicationTestCase.

 mApplication = (T) Instrumentation.newApplication(mApplicationClass, getContext()); 

Сообщение ClassCastException :

 java.lang.ClassCastException: android.test.mock.MockContext cannot be cast to android.app.ContextImpl 

Любые предложения, почему это происходит и как этого можно избежать?

EDIT: Связанный с этим вопрос: Android ApplicationTestCase с использованием MockContext

Solutions Collecting From Web of "AssertionFailedError в ApplicationTestCase.createApplication () в новых версиях Android при использовании MockContext"

Я тоже получаю такое поведение. Я работал над этим, расширяя ContextWrapper:

 public class RenamingMockContext extends RenamingDelegatingContext { private static final String PREFIX = "test."; public RenamingMockContext(Context context) { super(new ContextWrapper(context), PREFIX); } @Override public String getPackageName() { return PREFIX + super.getPackageName(); } } 

Метод Instrumentation.newApplication() вернет объект Application . Вы пытаетесь применить его к тому, что есть. Если T не является суперклассом или подклассом Application вы получите ClassCastException . В Java вы можете только передать объект тому, что является суперклассом или подклассом этого объекта. Если это не так, будет выбрано исключение.

НАПРИМЕР:

 Object x = new Integer(0); System.out.println((String)x); 

Это вызовет ClassCastException во второй строке, потому что вы пытаетесь ClassCastException x (объект Integer ) в String . Поскольку String и Integer не являются суб или супер-классами друг друга.