Тестирование кода Android с помощью JUnit и JDK - PullRequest
11 голосов
/ 12 сентября 2011

Я пишу несколько тестов POJO для моего кода Android.

Я хочу запускать их локально с JDK (не с Dalvik на эмуляторе) - для скорости, JUnit 4, Mockito и для возможности безголового запуска без устройства - поэтому у меня есть отдельный проект "Java" в Eclipse .

Если метод, который я тестирую, ссылается на что-то из Android SDK, например android.util.Log, тест не пройден - это имеет смысл, потому что android.jar не в пути к классам. Для воспроизведения у меня есть этот контрольный пример:

public class FooTests {
  @Test
  public void testFoo() {
    android.util.Log.d("x", "y");
  }
}

Если я добавлю android.jar явно к пути к классу тестового проекта, я получу исключения, такие как

java.lang.RuntimeException: Stub!
  at android.util.Log.d(Log.java:7)
  at com.example.FooTests.testFoo(FooTests.java:39)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  ...
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Есть ли способ заставить код работать, не устраняя каждый последний бит зависимости Android SDK? Возможно, вычеркнутый android.jar уже существует?

РЕДАКТИРОВАТЬ : На данный момент я закончил оборачивать классы типа android.util.Log и вставлять их в экземпляры для классического тестирования на основе IOC. Предложение Скотта PowerMock - мой следующий шаг, когда он мне понадобится.

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ : Робоэлектрик !

Ответы [ 5 ]

4 голосов
/ 26 июня 2012

У меня была такая же проблема.Я хотел протестировать простые POJO локально.
В частности, мой код хотел использовать android.util.Base64.
В итоге я использовал SDK для установки источников Android 4 и скопировал android.utilКласс BaseB64 для моего проекта.
Удивительно, но это сработало.

3 голосов
/ 12 сентября 2011

Нет знакомого мне android.jar. Я использую Powermock, чтобы макетировать все. Одна вещь, которую вы можете сделать, чтобы помочь с тяжелым издевательством, - это сделать ваши расширенные классы андроида, такие как активность, фрагменты, вещатели и т. Д. Тонкими, и заставить их делегировать классы pojo. Вы можете принять решение, основанное на оценке риска, не проводить модульное тестирование расширенных классов Android, а вместо этого тестировать модуль интеграции с помощью платформы тестирования Android или чего-то еще, например, Robotium.

Для истинного модульного тестирования изоляции в Android, для меня модульное тестирование на java jvm, которое вырубает все сотрудничающие классы, является лучшим способом.

2 голосов
/ 08 октября 2013

У меня была такая же проблема.Я хотел проверить простую бизнес-логику локально.В частности, мой код использует android.util.SparseArray<E>.

. Я попробовал 3 различных подхода, чтобы сделать его тестируемым с помощью junit за пределами Android.

  • В своей бизнес-логике я создал интерфейс и прикрепил его кMySparseArray<E>, который наследуется от SparseArray<E>.В тесте junit я повторно реализовал интерфейс, используя HashMap<Integer, E>.Это работает, но в долгосрочной перспективе это большая работа, чтобы сделать бизнес-логику тестируемой модулем, если требуются другие android.*.
  • Как предложил @Tal Weiss, я добавил исходные коды Java для Android необходимых классов:android.util.SparseArray.java, который использует com.android.internal.util.ArrayUtils.java.Это тоже работает, но я не люблю добавлять больше источников Android, особенно если есть гораздо больше зависимостей
  • Я скачал бесплатный бинарный файл android.jar для старого Android 2.2 с http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1и включил его как lib в мой junit-java-проект.Этот jar содержит только классы для пространств имен android.*, com.android.*, dalvik.* и framework.base.*.Это тоже работает.

В настоящее время мне удалось избежать использования android.* классов, кроме SparseArray<E> в моем бизнес-уровне, и он не зависит от Context, Activity или Service.Я мог бы использовать HashMap<Integer, E> на уровне android-business вместо SparseArray<E>.

1 голос
/ 09 августа 2015

unmock-плагин может помочь https://github.com/bjoernQ/unmock-plugin. В моем случае это работает с SparseArray.

0 голосов
/ 12 сентября 2011

Не встроенные тесты Android / Junit делать то, что вы хотите?

...