Mockito + Dexmaker на Android
Я пытаюсь использовать Mockito в моем проекте Android. Я нашел очень хороший учебник, который занимается этим: http://www.paulbutcher.com/2012/05/mockito-on-android-step-by-step/
В основном он использует новую версию Mockito + Dexmaker и все работает как положено.
Тем не менее, когда я пытаюсь смоделировать какой-то конкретный объект Android, т.е.
Context context = mock(Context.class);
Я получаю это исключение:
java.lang.IllegalArgumentException:
dexcache == null (and no default could be found;
consider setting the 'dexmaker.dexcache' system property)
at com.google.dexmaker.DexMaker.generateAndLoad(DexMaker.java:359)
at com.google.dexmaker.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:252)
at com.google.dexmaker.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:54)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
Есть идеи как это исправить?
6 ответов
Из комментария @rjath к ответу @MrChaz это работает лучше для меня:
System.setProperty(
"dexmaker.dexcache",
getInstrumentation().getTargetContext().getCacheDir().getPath());
Я положил это в свой setUp()
метод.
Мне удалось собрать воедино исправление, которое, кажется, работает для меня. К манифесту я добавил внешнее хранилище для чтения и записи. К тесту я добавил System.setProperty("dexmaker.dexcache", "/sdcard");
к тесту. К образу эмулятора я добавил SD-карту.
Я считаю, что это работает, потому что по умолчанию mockito пытается использовать каталог кэша приложений, но я никогда не запускаю действия, поэтому я подозреваю, что каталог никогда не создается ОС
Таким образом, проблема в том, что Dexmaker не может найти путь кеша на Android >= 4.3, как упоминали другие люди, и как описано в этой проблеме dexmaker.
Я пошел с реализацией обходного пути в специализированном инструментальном тестере, а не в каждом тесте (или их суперклассе) setUp()
потому что он кажется немного менее хакерским (на самом деле он находится только в одном месте - и не унаследован в каждом подклассе) и более гибким. Ради документации это необходимые изменения, чтобы сделать это:
public class CustomInstrumentationTestRunner extends InstrumentationTestRunner {
@Override public void onCreate (final Bundle arguments) {
super.onCreate(arguments);
// temporary workaround for an incompatibility in current dexmaker (1.1) implementation and Android >= 4.3
// cf. https://code.google.com/p/dexmaker/issues/detail?id=2 for details
System.setProperty("dexmaker.dexcache", getTargetContext().getCacheDir().toString());
}
}
И настройте свой проект (или тестовый проект), чтобы использовать этот класс в качестве инструментированного AndroidManifest.xml
при сборке с муравьем:
<instrumentation
android:name="my.package.CustomInstrumentationTestRunner"
android:targetPackage="my.target.package" />
или его build.gradle
при сборке с Gradle:
android {
defaultConfig {
// ...
testInstrumentationRunner 'my.package.CustomInstrumentationTestRunner'
}
// ...
}
Если у вас есть другие instrumentation
записи, вы можете переключаться между ними либо в командной строке, либо выбрать один в вашей рабочей конфигурации IDE.
У меня была эта проблема для проекта библиотеки Android, но НЕ для проекта приложения! Установка системного свойства "dexmaker.dexcache", как упомянуто выше, обошла проблему. У меня устройство Android 4.3 Nexus 4, сборка с инструментами 19.0.3, target api 19, мои зависимости:
androidTestCompile "org.mockito:mockito-core:1.9.5"
androidTestCompile "com.google.dexmaker:dexmaker:1.0"
androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.0"
Похоже, проект dexmaker перешел с Google Code на GitHub.
В центральном репозитории maven есть версии 1.1 и 1.2, опубликованные в марте 2014 года и декабре 2014 года.
Я подтвердил, что эта проблема "dexcache == null" все еще существует в версии 1.2 - но только на некоторых устройствах. Например, у Galaxy S5 с Android 5.0 есть проблема, а у Galaxy S4 с Android 4.4.2 нет.
Я клонировал GitHub-репозиторий ( последний коммит 12 марта 2015 - ca74669) и работал локально, и проблема была исправлена (в истории также есть коммиты, которые поддерживают это). Так что, как только выйдет версия 1.3, надеюсь, эта проблема исчезнет!
Любой, кто хочет запустить локальную копию 1.3-SNAPSHOT, вот как я это сделал (на Mac, но и на других платформах должно работать, вам понадобятся mvn, adb и dx на PATH):
git clone
https://github.com/crittercism/dexmaker.gitcd dexmaker
mvn install -Dmaven.test.skip=true
cp -R ~/.m2/repository/com/google/dexmaker $ANDROID_HOME/extras/android/m2repository/com/google
- Затем измените версию в
app/build.gradle
:androidTestCompile 'com.google.dexmaker:dexmaker:1.3-SNAPSHOT'
- Или же
pom.xml
если вы используете maven для создания или перезаписиlibs/dexmaker.jar
с~/.m2/repository/com/google/dexmaker/dexmaker/1.3-SNAPSHOT/dexmaker-1.3-SNAPSHOT.jar
если вы используете eclipse/ant
- Или же
Кроме того, к вашему сведению, оригинальный отчет о проблеме для той же проблемы в Google Code.
Вместо этого вы можете добавить ядро mockito в качестве зависимости. Тогда эта ошибка не произойдет, и вам не понадобится обходной путь.
dependencies {
...
testCompile 'org.mockito:mockito-core:1.10.19'
}
Я наблюдал эту проблему при манипуляциях с ресурсами и папками внутри test
папка. На самом деле помог просто перезапуск Android Studio. Просто, но сработало.