2012-09-22 80 views
4

首先,有類似的問題,如herehere,但我沒有一些外部庫,也沒有lib文件夾,也沒有一些包括罐子什麼的,所以我想知道我在做什麼錯誤Android Junit測試。NoClassDefFoundError執行Android JUnit測試時

我的項目結構如下:
enter image description here

正如你可以看到我有針對Android JUnit測試一個單獨的項目。測試類看起來是這樣的:

public class PersistenceManager { 
    private static final String FILENAME = "kpzwien_storage"; 

    public static void persist(String data, Context context) throws IOException { 
     FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE); 
     fos.write(data.getBytes()); 
     fos.close(); 
    } 

    public static String read(Context context) throws IOException { 
     FileInputStream fis = context.openFileInput(FILENAME); 
     StringBuffer fileContent = new StringBuffer(""); 

     byte[] buffer = new byte[1024]; 
     while (fis.read(buffer) != -1) { 
      fileContent.append(new String(buffer)); 
     } 

     return fileContent.toString(); 
    } 
} 

,這裏是它的測試用例:

public class PersistenceManagerTest extends AndroidTestCase { 

    private final String FILENAME_PREFIX = "test."; 

    @Before 
    public void setUp() { 
     MockContentResolver resolver = new MockContentResolver(); 
     RenamingDelegatingContext renamingDelegatingContext = new RenamingDelegatingContext(new MockContext(), getContext(), FILENAME_PREFIX); 
     Context context = new IsolatedContext(resolver, renamingDelegatingContext); 

     setContext(context); 
    } 

    public void testPersistAndRead() throws IOException { 
     String testData = "foobar"; 

     PersistenceManager.persist(testData, getContext()); 

     String result = PersistenceManager.read(getContext()); 

     assertEquals(testData, result); 
    } 
} 

測試項目的清單如下:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="net.devgems.android.kurzparkzonewien.androidtests" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="4" /> 

    <instrumentation 
     android:name="android.test.InstrumentationTestRunner" 
     android:targetPackage="net.devgems.android.kurzparkzonewien.activities" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <uses-library android:name="android.test.runner" /> 
    </application> 
</manifest> 

targetPackage是應用程序Instrumentation對象將根據元素在它的清單文件中分配的包名稱標識運行。 (來源:http://developer.android.com/guide/topics/manifest/instrumentation-element.html

包在我的主項目的名稱是

package="net.devgems.android.kurzparkzonewien.activities"

所以這也正是targetPackage點,如果我爲「Android的JUnit測試」跑,我總是得到的NoClassDefFoundError但??爲什麼任何想法,我使用ADT 20.0.3的Eclipse朱諾

最後這裏是logcat的輸出:

09-22 16:00:12.745: I/TestRunner(1528): java.lang.NoClassDefFoundError: net.devgems.android.kurzparkzonewien.controller.PersistenceManager 09-22 16:00:12.745: I/TestRunner(1528): at net.devgems.android.kurzparkzonewien.androidtests.PersistenceManagerTest.testPersistAndRead(PersistenceManagerTest.java:32) 09-22 16:00:12.745: I/TestRunner(1528): at java.lang.reflect.Method.invokeNative(Native Method) 09-22 16:00:12.745: I/TestRunner(1528): at java.lang.reflect.Method.invoke(Method.java:521) 09-22 16:00:12.745: I/TestRunner(1528): at junit.framework.TestCase.runTest(TestCase.java:154) 09-22 16:00:12.745: I/TestRunner(1528): at junit.framework.TestCase.runBare(TestCase.java:127) 09-22 16:00:12.745: I/TestRunner(1528): at junit.framework.TestResult$1.protect(TestResult.java:106) 09-22 16:00:12.745: I/TestRunner(1528): at junit.framework.TestResult.runProtected(TestResult.java:124) 09-22 16:00:12.745: I/TestRunner(1528): at junit.framework.TestResult.run(TestResult.java:109) 09-22 16:00:12.745: I/TestRunner(1528): at junit.framework.TestCase.run(TestCase.java:118) 09-22 16:00:12.745: I/TestRunner(1528): at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169) 09-22 16:00:12.745: I/TestRunner(1528): at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154) 09-22 16:00:12.745: I/TestRunner(1528): at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430) 09-22 16:00:12.745: I/TestRunner(1528): at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447) 09-22 16:00:12.745: I/TestRunner(1528): ----- end exception -----

+0

不應該你的測試用例類有一個構造函數嗎?我沒看到它。 像在Android的例子:http://developer.android.com/tools/testing/activity_test.html –

+0

我不測試一個活動。應該如何構造? – Bevor

+0

順便說一下,AndroidTestCase中沒有這樣的構造函數。 – Bevor

回答

2

我找到了解決方案。但它實際上是一種解決方法,因爲我不能形象,我通常需要這樣修補(也許有人知道更好的解決方案?):

我的主項目是一個Maven項目,在這個項目中我必須設置從/倉...構成的輸出文件夾到/ 目標/類目標/測試類目標/生成來源。我這樣做是因爲否則,只要我不運行mvn install,主項目中的JUnit測試無法找到最新的代碼更改。。如果輸出文件夾是target/...,我不需要運行mvn install以在我的測試中有最新更改。
現在的問題是,當Android測試項目存儲在主項目的目標中時,它找不到編譯的源代碼。當我將主項目中的輸出文件夾設置爲bin並運行mvn install時,Android測試項目現在可以找到類。我只需要這樣做一次。當我將其設置回目標時,我的Android測試仍然運行,並且運行了我的主要JUnit測試。當我更改主項目中的方法時,測試項目會立即識別這些更改,這意味着它不會使用二進制jar或其他東西(這確實非常好,儘管我不明白它爲什麼會發現它,儘管我把它設置回目標?)。

[更新]
添加上述兩行的主要項目的POM建部分解決了這個問題,所以我並不需要一個解決辦法了。

<outputDirectory>bin/classes</outputDirectory> 
    <testOutputDirectory>bin/test-classes</testOutputDirectory>