Получение ClassNotFoundException при запуске Robolectric тестов с плагином Maven surefire - PullRequest
4 голосов
/ 16 августа 2011

Я создал проект в Eclipse, используя интеграцию с Android Maven и Robolectric для некоторых тестов.

Тесты запускаются нормально, когда я развертываю их в Eclipse. Однако, когда я пытаюсь собрать проект с целью Maven * install (это на самом деле библиотека, которая мне нужна в моем локальном репозитории Maven), он не проходит в тех же тестах.

Журналы показывают следующую ошибку:

testAll((package).MyTest)  Time elapsed: 0.006 sec  <<< ERROR!
java.lang.RuntimeException: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for (package).R
    at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:316)
    at com.xtremelabs.robolectric.RobolectricTestRunner.setupApplicationState(RobolectricTestRunner.java:270)
    at com.xtremelabs.robolectric.RobolectricTestRunner.internalBeforeTest(RobolectricTestRunner.java:221)
    at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:201)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:120)
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:103)
    at org.apache.maven.surefire.Surefire.run(Surefire.java:169)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
    at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
Caused by: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for (package).R
    at javassist.Loader.findClass(Loader.java:359)
    at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.findClass(RobolectricClassLoader.java:60)
    at javassist.Loader.loadClass(Loader.java:311)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.loadClass(RobolectricClassLoader.java:37)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)
    at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:312)
    ... 22 more
Caused by: com.xtremelabs.robolectric.bytecode.IgnorableClassNotFoundException: msg because of javassist.NotFoundException: (package).R
    at com.xtremelabs.robolectric.bytecode.AndroidTranslator.onLoad(AndroidTranslator.java:80)
    at javassist.Loader.findClass(Loader.java:340)
    ... 29 more

где (пакет) - это, конечно, название моего основного пакета. Вот соответствующий раздел моего POM:

  <dependencies>
    <dependency>
      <groupId>com.google.android</groupId>
      <artifactId>android</artifactId>
      <version>2.1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.pivotallabs</groupId>
        <artifactId>robolectric</artifactId>
        <version>0.9.8</version>
        <type>jar</type>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-core</artifactId>
        <version>1.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.2</version>
        <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
   <defaultGoal>package</defaultGoal>
    <plugins>
      <plugin>
        <groupId>com.jayway.maven.plugins.android.generation2</groupId>
        <artifactId>maven-android-plugin</artifactId>
        <version>2.8.3</version>
        <configuration>
        <genDirectory>${project.basedir}/gen</genDirectory>
          <androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
          <assetsDirectory>${project.basedir}/assets</assetsDirectory>
          <resourceDirectory>${project.basedir}/res</resourceDirectory>
          <nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory>
          <sdk>
            <platform>7</platform>
          </sdk>
          <deleteConflictingFiles>true</deleteConflictingFiles>
          <undeployBeforeDeploy>true</undeployBeforeDeploy>
        </configuration>
        <extensions>true</extensions>
      </plugin>

      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <excludes>
                <exclude>**/Test*.java</exclude>
            </excludes>
        </configuration>
    </plugin>      
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>2.8</version>
    </plugin>
    </plugins>
  </build>

Как видите, я попытался добавить опцию "genDirectory" в плагин Maven для Android. Но безрезультатно.

Чего мне не хватает, чтобы плагин безошибочной работы "увидел" класс R?

Еще одна вещь: мой класс на самом деле не ссылается на класс R.

Ответы [ 4 ]

4 голосов
/ 27 февраля 2013

Я обнаружил, что единственный способ решить эту проблему - поместить поддельный файл R.java в пакет:

    public class R {
        public static final class attr {
        }

        public static final class drawable {
        }

        public static final class id {
        }

        public static final class layout {
        }

        public static final class string {
        }
    }

Это должно быть необходимо только при следующих обстоятельствах:

  1. Проект библиотеки Maven
  2. зависимости модульного теста от Robolectric
  3. R.java не создается или не обнаруживается в пути к классам maven.

Примечание: Вы можетепоместите R.java в исходные тексты тестов, чтобы он не был развернут.Это не будет мешать созданию реальных ресурсов.

4 голосов
/ 08 августа 2012

Я тоже получил именно эту проблему.

Поэтому я тщательно сравнил проект RobolectricSample и мой проект.

К моему удивлению, проект RobolectricSample также НЕ МОЖЕТ работать, если я сначала не запустил командную строку mvn clean test.

Поэтому я проанализировал разницу и обнаружил, что командная строка тоже компилировала "gen / xxx / R.java" в "target / classes / xxx / R".

Это хитрость успеха, поэтому я сделал следующие шаги: 1. щелкните правой кнопкой мыши проект -> Java Build; 2. измените выходную папку "{project} / gen" на "target / class" (вместо оригинальных "target / android-classes")

Вот и все, надеюсь, это поможет.

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

У меня была такая же проблема, когда я пытался запустить тест из Eclipse, впервые после добавления Robolectric.

Что решило проблему для меня, так это mvn clean test в командной строке.После этого тест запустился и в Eclipse.

И убедитесь, что в вашем pom.xml есть <packaging>apk</packaging>.

0 голосов
/ 28 ноября 2012

У меня была такая же проблема при запуске Robolectric тестов как в eclipse, так и в командной строке через mvn clean test.Т.е. java.lang.ClassNotFoundException жалуется, что мой файл R.class не найден.Действительно, файла R.class не было, так как мой проект представляет собой библиотеку Android, в которой нет ресурсов.

A dirty hack Чтобы избавиться от ошибки, нужно создать файл <project-home>/res/values/strings.xml с одной неиспользуемой строкой.Затем генерируется R.java и соответствующий класс R. и ошибка исчезает.

...