2011-08-16 110 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

是的,這是我做我的包裝類型保持罐子 –

相關問題