2012-09-22 78 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>