Подтвердить что ты не робот

Mockito + Dexmaker на Android

Я пытаюсь использовать Mockito в своем проекте Android. Я нашел очень хороший учебник, который занимается этим: http://www.paulbutcher.com/2012/05/mockito-on-android-step-by-step/

В основном используется новая версия Mockito + Dexmaker, и все работает так, как ожидалось.
Однако, когда я пытаюсь высмеять некоторые специфические объекты Android i.e:

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)

Есть идея, как это исправить?

4b9b3361

Ответ 1

Из комментария @rjath ответа @MrChaz, это работает лучше для меня:

System.setProperty(
    "dexmaker.dexcache",
    getInstrumentation().getTargetContext().getCacheDir().getPath());

Я поместил его в мой метод setUp().

Ответ 2

Мне удалось собрать исправление, которое, похоже, работает для меня. В манифест я добавил чтение и запись внешнего хранилища. К тесту я добавил System.setProperty("dexmaker.dexcache", "/sdcard"); к тесту. На изображение эмулятора я добавил SD-карту.

Я считаю, что это работает, потому что по умолчанию mockito пытается использовать каталог кеша приложений, но я никогда не запускаю действие, поэтому я подозреваю, что каталог никогда не создается ОС

Ответ 3

Таким образом, проблема заключается в том, что 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 при создании с помощью ant:

<instrumentation
    android:name="my.package.CustomInstrumentationTestRunner"
    android:targetPackage="my.target.package" />

или его build.gradle при создании с помощью gradle:

android {
    defaultConfig {
        // ...
        testInstrumentationRunner 'my.package.CustomInstrumentationTestRunner'
    }
    // ...
}

Если у вас есть другие записи instrumentation, вы можете переключаться между ними как в командной строке или выбрать один из них в вашей конфигурации IDE.

Ответ 4

У меня была эта проблема для проекта Android Library, но НЕ для проекта приложения! Установка свойства System "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"

Ответ 5

Похоже, проект 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 (last commit 12 марта 2015 года - ca74669) и запускался локально, и проблема была исправлена ​​(там также фиксируются в истории, которые подтверждают это). Поэтому, когда есть версия 1.3, надеюсь, эта проблема ушла навсегда!

Любой, кто хочет запустить локальную копию 1.3-SNAPSHOT, вот как я это сделал (на Mac, но другие платформы тоже должны работать, вам понадобятся mvn, adb и dx на PATH):

  • git clone https://github.com/crittercism/dexmaker.git
  • cd 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

Кроме того, FYI, исходный отчет об ошибках для той же проблемы в Google Code.

Ответ 6

Вместо этого вы можете добавить ядро ​​mockito в качестве зависимости. Тогда эта ошибка не произойдет, и вам не понадобится обходной путь.

dependencies {
   ... 
   testCompile 'org.mockito:mockito-core:1.10.19'
}