аннотации Android, gradle и robolectric: java.lang.NoClassDefFoundError: org/androidannotations/api/view/HasViews

Мне удалось заставить Robolectric работать над проектом Gradle. Теперь у меня проблема с тем, чтобы заставить его работать с аннотациями Android. Поэтому я уже присоединил тестовый пакет к основному пакету (сгенерированные классы аннотаций Android имеют только видимость пакета). Я прочитал раздел о модульном тестировании на https://github.com/excilys/androidannotations/wiki/Unit-test-your-application.

Хорошо работает любой тест, не касающийся деятельности, например:

@Test
public void testTrueIsTrue() throws Exception {
    Assertions.assertThat(true);
}

Теперь проблема в том, что при попытке выполнить тест, касающийся действий и их жизненных циклов, тест завершается с ошибкой NoClassDefFoundError. У вас есть идея, как проверить активность? Тест по этому поводу, например:

@Test
public void testActivity() {
    MainActivity_ mainActivity = new MainActivity_();
    mainActivity.onCreate(null);
    Assert.assertNotNull(mainActivity);
}

or

@Test
public void testRobolectricActivity() {
    ActionBarActivity activity = Robolectric.buildActivity(MainActivity_.class).create().get();
    Assert.assertNotNull(activity);
}

Результирующая ошибка и ее трассировка стека для последнего теста:

java.lang.NoClassDefFoundError: path/to/project/app/ui/MainActivity_
at path.to.project.test.MainActivityRobolectricTest.testRobolectricActivity(MainActivityRobolectricTest.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:250)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Для первого теста

java.lang.NoClassDefFoundError: org/androidannotations/api/view/HasViews
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
at org.robolectric.bytecode.AsmInstrumentingClassLoader.findClass(AsmInstrumentingClassLoader.java:165)
at org.robolectric.bytecode.AsmInstrumentingClassLoader.loadClass(AsmInstrumentingClassLoader.java:98)
at path.to.projet.test.MainActivityRobolectricTest.testActivity(MainActivityRobolectricTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:250)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.ClassNotFoundException: org.androidannotations.api.view.HasViews
at org.robolectric.bytecode.AsmInstrumentingClassLoader.findClass(AsmInstrumentingClassLoader.java:131)
at org.robolectric.bytecode.AsmInstrumentingClassLoader.loadClass(AsmInstrumentingClassLoader.java:98)... 43 more

Буду признателен за помощь. Заранее спасибо.


person Morton    schedule 11.06.2014    source источник
comment
В трассировке стека вы также можете увидеть, как я сейчас структурировал свои пакеты. Может это все еще проблема?   -  person Morton    schedule 11.06.2014


Ответы (3)


Я не использовал roboelectric, но похоже, что АА не генерирует классы.

Загляните в папку apt_generated для MainAcitvity_ проверьте, что файл есть и в нем есть метод hasviews.

Во-вторых, имеет ли это значение приведение к несгенерированному классу

@Test
public void testActivity() {
    MainActivity mainActivity = new MainActivity_();
    mainActivity.onCreate(null);
    Assert.assertNotNull(mainActivity);
}
person Brian    schedule 12.06.2014

У меня была аналогичная проблема. Проблема в том, что сгенерированные классы до сих пор не найдены из-за ошибки. И я вижу, вы также используете версию SNAPSHOT, которая была и у меня.

Я не уверен, но в моем случае аннотации Android не сказали мне, что в моем аннотированном коде была ошибка, но я проверил недавно закодированные методы и понял, что один из моих методов, аннотированных с помощью @Background, имеет частный доступ. В этом была проблема. После создания локального пакета все снова заработало.

Другая проблема может заключаться в том, что вы неправильно указали каталог сборки в параметре test vm. Поэтому вы должны сделать следующее:

Сбросьте параметры виртуальной машины в настройках редактирования на -ea (по умолчанию). После этого вы получите ЗАГЛУШКУ! исключение при выполнении вашего теста, который жалуется на версию junit. Скопируйте все поверх консоли исключений (она немного серая, и вам придется ее открыть) в редактор, удалите все до -classpath и все в конце, что не принадлежит пути к классам (означает, что не разделены: и добавьте за последним путем ваш каталог сборки:

В моем случае это выглядит так:

-classpath /home/user/.gradle/caches/modules-2/files-2.1/junit/junit/4.12-SNAPSHOT/d0f5ec9e335da2ea2827c781a46a02d8b6bbd556/junit-4.12-SNAPSHOT.jar:/home/user/android-studio/lib/idea_rt.jar:/home/user/android-studio/plugins/junit/lib/junit-rt.jar:/home/user/android-sdk/platforms/android-19/android.jar:/home/user/android-sdk/platforms/android-19/data/res:/home/user/android-sdk/tools/support/annotations.jar:   [... deleted some dependencies here ...]   /home/user/.gradle/caches/modules-2/files-2.1/org.robolectric/robolectric/2.4-SNAPSHOT/78161192eaadd6c7c56f6cf48040fa46897163d0/robolectric-2.4-SNAPSHOT.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm-util/5.0.1/7c8caddfbd0b2d7b844f8fcc75175b9cb9cf4724/asm-util-5.0.1.jar:/home/user/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.3-SNAPSHOT/90850100a41d5695e2780773e2fc33198dea70d/gson-2.3-SNAPSHOT.jar:/home/user/development/App/app/build/generated

После этого классы должны быть найдены.

Надеюсь, это поможет...

person luckyhandler    schedule 18.06.2014

Я не понимаю вашу проблему, не видя настройки вашего проекта. Я могу просто показать, что аннотации robolectric и android работают вместе. Здесь в моем примере шаблон приложения с тестированием активности https://github.com/nenick/android-gradle-template

person nenick    schedule 26.06.2014