2011-08-16 77 views
4

我在Eclipse中使用Android Maven集成和Robolectric进行了一些测试。使用Maven surefire插件运行Robolectric测试时获取ClassNotFoundException

当我在Eclipse中部署它们时,测试运行良好。但是,当我尝试使用Maven“安装”目标(这实际上是我在本地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插件。但无济于事。

我错过了什么让surefire插件“看”R类?

还有一件事:R类实际上没有被我的代码引用。

+0

你是什么意思“安装”目标? Eclipse具有用于执行应用程序的运行和调试模式。安装由Android SDK处理。如果您特意从Maven/Robolectric代码中获取错误,请确保将它们包含在构建路径中。 – Codeman

+0

“安装”目标是特定于Maven的操作 - 它将您的项目添加到本地Maven存储库(该项目实际上是一个库)。换句话说 - 这是独立于Eclipse运行周期的东西。我会在这方面编辑我的问题,使之更清晰。 –

+0

R.java类是由Android编译的 - 您不应该在Android项目之外引用它,特别是,您不能在没有活动引用的情况下引用它。 – Codeman

回答

3

我在尝试从Eclipse运行测试时遇到了同样的问题,第一次在添加Robolectric之后。

什么解决了这个问题对我来说是mvn clean test在命令行上。之后,测试也从Eclipse运行正常。

并确保你在你的pom.xml有<packaging>apk</packaging>

+0

不幸的是,没有奏效。如果这不是太大的问题,你可以在你的POM中编辑吗?也许我有一些配置错误... –

+0

不确定你的意思是“这实际上是一个图书馆”。我有' apk'在我的朋友。如果我用' jar'替换它,那么它会失败,并显示“包R不存在”。 – altumano

+0

...当然,这工作(我想让这个用法更方便一些,直到我设置了一个Maven回购,并且这个回火)。谢谢! 您可以添加信息来将包装设置为“apk”,以便我可以接受并注销它? –

4

我也正是这个问题。

所以我仔细比较了RobolectricSample项目和我的项目。

令我吃惊的是,RobolectricSample项目还不能,如果我不跑“MVN清洁测试”的命令行中第一个工作。

因此我分析的差异,并发现编着的“根/ XXX/R.java”到“目标/类/ XXX/R”太命令行。

,这是成功的诀窍,所以我做了以下步骤: 1.右击项目 - > Java构建; 2.将“{project}/gen”输出文件夹更改为“target/class”(而不是原始的“target/android-classes”)

就是这样,希望这有助于。

0

我有同样的问题,无论是在Eclipse和通过mvn clean test在命令行中运行时,测试Robolectric。即一个java.lang.ClassNotFoundException抱怨我的R.class文件没有找到。事实上,没有R.class文件,因为我的项目是一个没有资源的Android库。

一个肮脏的黑客摆脱错误的是创建一个<project-home>/res/values/strings.xml文件与一个未使用的字符串。然后生成R.java和相应的R.class,错误消失。

4

我发现解决这个问题的唯一方法是放置一个假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 classpath中找到。

注意:您可以将R.java放在测试源中,以便它不被部署。这样就不会干扰创建的实际资源。

+0

是的,这是我做我的包装类型保持罐子 –

相关问题